有T种物品,每种物品有a[i]个,同种类物品不区分,从中取出i个的方法为f(i),求
设dp[i][j]是前i种物品,拿出j个方法数
那么对每一层i,其中的每个dp[i][j]
,dp[i][j]=
划分的再详细一点:
对于j>=a[i]的,dp[i][j]=
对于a[i]>=j的,dp[i][j]=
这样就能 算出所有的dp[i][j],而答案就是
但是直接这样算,复杂度肯定会爆的,这个时候,就有一个本菜鸡还不熟练的思想,利用前面计算的结果
对于j>=a[i]的,dp[i][j]=dp[i][j-1]+dp[i-1][j]
对于j<a[i],dp[i][j]相比dp[i][j-1]增加了一个dp[i-1][j],减少了一个dp[i-1][j-a[i]-1],再加上就好啦
所以dp[i][j]=dp[i][j-1]+dp[i-1][j]-dp[i-1][j-a[i]-1],
终于AC的代码,一定要吸取到这种思想,这次还在Onenote上给自己做题的顺序,流程做了规定
希望能遵守,希望能减少Bug
代码:
//Problem:
//Date:
//Skill:
//Bug:
/////////////////////////////////////////definations////////////////////
#define CLR(a) memset((a),0,sizeof(a))
#define RE(i,n) for(int i=0;i<n;i++)
#define RE2(i,n) for(int i=1;i<=n;i++)
#define IN(n) scanf("%d",&n)
#define LLIN(n) scanf("%lld",&n)
#define INC(c) do{scanf("%c",&c);}while(isspace(c))
#define PI(a) printf("%d",a)
#define LLPI(a) printf("%lld",a)
#define PN puts("");
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;
const long long llinf = 0x3f3f3f3f3f3f3f3f;
const int inf = 0x3f3f3f3f;
///////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////options////////////////////////////////
const int maxn = int();
typedef long long ll;
#define CPP_IO
//#define LOCAL
#ifdef CPP_IO
#include<iostream>
#include<iomanip>
#include<string>
#else
#include<stdio.h>
#endif
///////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////Added Functions/////////////////////
int a[1010];
int dp[1010][100010];
///////////////////////////////////////////////////////////////////////////
int main()
{
#ifdef LOCAL
freopen("C:\\Users\\VULCAN\\Desktop\\data.in", "r", stdin);
#endif //LOCAL
#ifdef CPP_IO
std::ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
#endif // CPP_IO
//How to think:
//先认真读题,把题目逻辑化,读清全部条件,再做,不然,哼哼
//写题的时候遇到的一些”莫名“的错误大部分是自己的代码写错了一个变量
//1.分治 2.容斥 3.化多元为单元
//4.dp 分阶段,后阶段受前阶段的影响
//5.凡是有很大的指数的,都可以先用log算一下
//6.预处理,作用非常大,很快
//
//1.Do you use cout/cin? Do not use!
//2.what's the maximum Int data? Is it beyond I32d?
//3.Ever Mod after neccesary calculation?
//4.Ever Cleaned the array before using?
///////////////////////////////////////////code////////////////////////////////
int T(1), times(0);
//IN(T);
while (++times, T--)
{
int temp, mod = 1000000;
int T, A, S, B; cin >> T >> A >> S >> B;
memset(a, 0, sizeof(a));
RE2(i, A)
cin >> temp,a[temp]++;
RE(i, T + 1)dp[i][0] = 1;
RE2(i, T)
{
RE2(j, B)
{
if (j > a[i])
{
dp[i][j] = dp[i - 1][j]
+ dp[i][j - 1]/*加一个*/
- dp[i - 1][j-1- a[i]];
dp[i][j] = (dp[i][j] + mod) % mod;
}
else
dp[i][j] = (dp[i][j - 1] + dp[i - 1][j]) % mod;
}
}
ll ans(0);
for (int i = S; i <= B; ++i)ans += dp[T][i],ans%=mod;
cout << ans << endl;
}
//////////////////////////////////////////////////////////////
//dividing line
return 0;
}