題目鏈接:點擊打開鏈接
題意:
有 T 種螞蟻家庭;
每個家庭 ai 個螞蟻;
給你一串序列,相同的數字代表是一個家庭;
問你這一串序列能組成多少不同的(1 ~ T)的集合;
理解:
雲裏霧裏;
書上原題;
是 dp 的多重集組合數;
直接套模板;
遞推式:dp[i + 1][j] = sigma(dp[i][j - k]);
其中 k 是 [0, min(j, a[i])];
變形如下:
dp[i + 1][j] = dp[i + 1][j - 1] + dp[i][j] - dp[i][j - 1 - a[i]];
其中 j 要滿足條件 j - 1 - a[i] >= 0;
代碼如下:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <stack>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int MIN_INF = 1e-7;
const int MAX_INF = (1e9) + 7;
#define X first
#define Y second
int dp[2][100100];
int ha[1010];
const int M = 1000000;
int main() {
int t, a, s, b;
cin >> t >> a >> s >> b;
for (int i = 0; i < a; ++i) {
int x;
cin >> x;
++ha[x];
}
dp[0][0] = 1;
dp[1][0] = 1;
int k = 0;
for (int i = 1; i <= t; ++i) {
for (int j = 1; j <= a; ++j) {
if (j - 1 - ha[i] >= 0) {
dp[(k + 1) % 2][j] = (dp[(k + 1) % 2][j - 1] + dp[k][j] - dp[k][j - 1 - ha[i]] + M) % M;
}
else {
dp[(k + 1) % 2][j] = (dp[(k + 1) % 2][j - 1] + dp[k][j]) % M;
}
}
k = (k + 1) % 2;
}
int ans = 0;
for (int i = s; i <= b; ++i) {
ans = (ans + dp[k][i]) % M;
}
cout << (ans + M) % M << endl;
return 0;
}