蚂蚁计数
描述
贝西有一天在蚂蚁山上戳戳,看着蚂蚁在收集食物时来回走动。
她意识到许多蚂蚁是兄弟姐妹,彼此之间没有区别。
她还意识到,有时只有一只蚂蚁会去觅食,有时是几只,有时都是。
这使得大量不同的蚂蚁!
由于有点数学,贝西开始思考。
贝西(Bessie)指出,该配置单元具有T(1 <= T <= 1,000)个蚂蚁家族,她将它们标记为1…T(一共一个蚂蚁)。
每个家庭都有一定数量的Ni(1 <= Ni <= 100)蚂蚁。
可以形成几组大小为S,S + 1,…,B(1 <= S <= B <= A)的大小?
在观察一组时,三个蚂蚁家族的集合被视为{1、1、2、2、3},尽管很少按该顺序排列。
可能的行军蚁集有:
3组,每组1只蚂蚁:{1} {2} {3}
5组,带有2只蚂蚁:{1,1} {1,2} {1,3} {2,2} {2,3}
5组,每组3种蚂蚁:{1,1,2} {1,1,3} {1,2,2} {1,2,3} {2,2,3}
3组,每组4个蚂蚁:{1,2,2,3} {1,1,2,2} {1,1,2,3}
1组,共5只蚂蚁:{1,1,2,2,3}
给定以上数据,您的工作是计算可能的蚂蚁集数量。
输入值
*第1行:4个以空格分隔的整数:T,A,S和B
*第2…A + 1行:每行包含一个整数,该整数是蜂巢中存在的一种蚂蚁类型
输出量
*第1行:可以创建的大小为S…B(含)的套数。
像{1,2}这样的集合与集合{2,1}相同,因此不应重复计算。
仅打印此数字的最后六个数字,没有前导零或空格。
样本输入
3 5 2 3
1
2
2
1
3
样本输出
10
暗示
输入详细信息:
三种类型的蚂蚁(1…3);
共有5只蚂蚁。
可以制作几套2号或3号规格?
输出详细信息:
5只蚂蚁,有两名成员;
五只蚂蚁,三只成员
dp[i + 1][j] 定义为从前i个物品(蚂蚁家族种类)取出j个的组合数。
//o(TB)
#include <cstdio>
#include <cstring>
using namespace std;
const int MAX = 1e3 + 5;
const int MAXN = 1e5 + 5;
int T, A, S, B;
int a[MAX];
int dp[MAX][MAXN];
const int MOD = 1e6;
int main() {
scanf("%d%d%d%d", &T, &A, &S, &B);
int AA;
for (int i = 0; i < A; i++) {
scanf("%d", &AA);
a[AA - 1]++;
}
long long ans = 0;
for (int i = 0; i <= T; i++) dp[i][0] = 1;
for (int i = 0 ; i < T ; i++) {
for (int j = 1; j <= B; j++) {
if(j - 1 < a[i])
dp[i + 1][j] = dp[i + 1][j - 1] + dp[i][j];
else
dp[i + 1][j] = dp[i + 1][j - 1] + dp[i][j] - dp[i][j - 1 - a[i]] + MOD; // 出现减法,要多加MOD再取模
dp[i + 1][j] %= MOD;
}
}
for (int j = S; j <= B; j++) {
ans += dp[T][j];
ans %= MOD;
}
printf("%lld\n", ans);
}