POJ3046 Ant Counting 【母函数】

Ant Counting

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 2924   Accepted: 1170

Description

Bessie was poking around the ant hill one day watching the ants march to and fro while gathering food. She realized that many of the ants were siblings, indistinguishable from one another. She also realized the sometimes only one ant would go for food, sometimes
a few, and sometimes all of them. This made for a large number of different sets of ants!

Being a bit mathematical, Bessie started wondering. Bessie noted that the hive has T (1 <= T <= 1,000) families of ants which she labeled 1..T (A ants altogether). Each family had some number Ni (1 <= Ni <= 100) of ants.

How many groups of sizes S, S+1, ..., B (1 <= S <= B <= A) can be formed?

While observing one group, the set of three ant families was seen as {1, 1, 2, 2, 3}, though rarely in that order. The possible sets of marching ants were:

3 sets with 1 ant: {1} {2} {3}

5 sets with 2 ants: {1,1} {1,2} {1,3} {2,2} {2,3}

5 sets with 3 ants: {1,1,2} {1,1,3} {1,2,2} {1,2,3} {2,2,3}

3 sets with 4 ants: {1,2,2,3} {1,1,2,2} {1,1,2,3}

1 set with 5 ants: {1,1,2,2,3}

Your job is to count the number of possible sets of ants given the data above.

Input

* Line 1: 4 space-separated integers: T, A, S, and B

* Lines 2..A+1: Each line contains a single integer that is an ant type present in the hive

Output

* Line 1: The number of sets of size S..B (inclusive) that can be created. A set like {1,2} is the same as the set {2,1} and should not be double-counted. Print only the LAST SIX DIGITS of this number, with no leading zeroes or spaces.

Sample Input

3 5 2 3
1
2
2
1
3

Sample Output

10

Hint

INPUT DETAILS:

Three types of ants (1..3); 5 ants altogether. How many sets of size 2 or size 3 can be made?

OUTPUT DETAILS:

5 sets of ants with two members; 5 more sets of ants with three members

Source

USACO 2005 November Silver

母函数版:344ms

#include <stdio.h>
#include <algorithm>
#include <string.h>
using namespace std;

const int mod = 1000000;
const int maxn = 1002;
const int maxm = 100002;

int dp[maxm], arr[maxn], c1[maxm], c2[maxm];

int main() {
    int T, A, S, B, i, j, k, v, sum;
    while(scanf("%d%d%d%d", &T, &A, &S, &B) != EOF) {
        memset(arr, 0, sizeof(int) * (T + 1));
        for(i = 0; i < A; ++i) {
            scanf("%d", &v);
            ++arr[v];
        }
        memset(c1, 0, sizeof(int) * (B + 1));
        memset(c2, 0, sizeof(int) * (B + 1));
        c1[0] = 1;
        for(i = 1; i <= T; ++i) {
            for(j = 0; j <= B; ++j)
                for(k = 0; k <= arr[i] && k + j <= B; ++k)
                    c2[j+k] = (c1[j] + c2[j+k]) % mod;
                for(j = 0; j <= B; ++j) {
                    c1[j] = c2[j]; c2[j] = 0;
                }
        }
        for(sum = 0, i = S; i <= B; ++i)
            sum = (sum + c1[i]) % mod;
        printf("%d\n", sum);
    }
    return 0;
}
时间: 2024-11-11 15:45:35

POJ3046 Ant Counting 【母函数】的相关文章

bzoj2023[Usaco2005 Nov]Ant Counting 数蚂蚁*&amp;&amp;bzoj1630[Usaco2007 Demo]Ant Counting*

bzoj2023[Usaco2005 Nov]Ant Counting 数蚂蚁&&bzoj1630[Usaco2007 Demo]Ant Counting 题意: t个族群,每个族群有ni只蚂蚁,同族群蚂蚁没有区别.问从所有蚂蚁中选出s到b只蚂蚁有多少方案.t≤1000,ni≤100. 题解: dp,f[i][j]表示考虑第i个族群,剩下j只蚂蚁没选择.则f[i][j]=sum(f[i-1][j-k]),k=0..min(j,n[i]).然而O(n^3)会超时,注意到可以计算f[i-1][

Ant Counting (poj 3046 分组背包)

Language: Default Ant Counting Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3142   Accepted: 1246 Description Bessie was poking around the ant hill one day watching the ants march to and fro while gathering food. She realized that man

BZOJ2023: [Usaco2005 Nov]Ant Counting 数蚂蚁

2023: [Usaco2005 Nov]Ant Counting 数蚂蚁 Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 56  Solved: 16[Submit][Status] Description 有一天,贝茜无聊地坐在蚂蚁洞前看蚂蚁们进进出出地搬运食物.很快贝茜发现有些蚂蚁长得几乎一模一样,于是她认为那些蚂蚁是兄弟,也就是说它们是同一个家族里的成员.她也发现整个蚂蚁群里有时只有一只出来觅食,有时是几只,有时干脆整个蚁群一起出来.这样一来,

1630/2023: [Usaco2005 Nov]Ant Counting 数蚂蚁

2023: [Usaco2005 Nov]Ant Counting 数蚂蚁 Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 85  Solved: 40[Submit][Status][Discuss] Description 有一天,贝茜无聊地坐在蚂蚁洞前看蚂蚁们进进出出地搬运食物.很快贝茜发现有些蚂蚁长得几乎一模一样,于是她认为那些蚂蚁是兄弟,也就是说它们是同一个家族里的成员.她也发现整个蚂蚁群里有时只有一只出来觅食,有时是几只,有时干脆整个蚁群一

poj 3046 Ant Counting

题目大意: 有编号一到t的蚂蚁家族,每个家族有不同的蚂蚁数. 问构成S只蚂蚁到构成B只蚂蚁共有多少种方式 例如 While observing one group, the set of three ant families was seen as {1, 1, 2, 2, 3}, though rarely in that order. The possible sets of marching ants were: 3 sets with 1 ant: {1} {2} {3} 5 sets

POJ 3046 Ant Counting ( 多重集组合数 &amp;&amp; 经典DP )

题意 : 有 n 种蚂蚁,第 i 种蚂蚁有ai个,一共有 A 个蚂蚁.不同类别的蚂蚁可以相互区分,但同种类别的蚂蚁不能相互区别.从这些蚂蚁中分别取出S,S+1...B个,一共有多少种取法. 分析 :  实际就是要解决 => 从 n 种物品中取出 m 个有多少种取法 ( 同种无法区分 ) 计数问题的 DP 定义必须保证不重复计数 这里定义 dp[i+1][j] => 从前 i 种物品中取出 j 个的组合数 根据定义为了从前 i 种物品中取出 j 个,可以从前 i-1 中取出 j-k 个并从 i

poj 3046 Ant Counting DP

大致题意:给你a个数字,这些数字范围是1到t,每种数字最多100个,求问你这些a个数字进行组合(不包含重复),长度为s到b的集合一共有多少个. 思路:d[i][j]——前i种数字组成长度为j的集合有多少个. 那么,当前考虑第i种数字,我要组成长度为j的集合,只用在前i-1种数字所组成的集合中,只要添加0...cnt[i]个第i种数字之后长度能够达到j的那些集合数加起来 所以方程可以写成d[i][j] = ∑(cnt[i],0)  d[i-1][j-k]. 每种数字最多100个,数字最大为1000

poj 3046 Ant Counting 多项式乘法解可重组合数

题意: 裸的求可重组合数. 分析: 多项式乘法求系数的应用啊,不用dp. 代码: //poj 3046 //sep9 #include <iostream> using namespace std; const int maxN=1024; const int maxL=100024; const int mod=1000000; int num[maxN]; int coef[maxL]; int tmp[maxL]; int l1; void mul(int l2) { for(int i

bzoj1630/2023 [Usaco2007 Demo]Ant Counting

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1630 http://www.lydsy.com/JudgeOnline/problem.php?id=2023 [题解] 直接dp,f[i,j]表示第i个种族选了j只蚂蚁的方案数,转移枚举这个种族选择的方案. 然后可以前缀和+滚动数组 # include <stdio.h> # include <string.h> # include <iostream> # i