Codeforces - 543A
N 个人写共计
M 行代码,第 i 个人每写一行代码就有ai 个bug
问使得 M 行代码都被写完,并且总 bug不超过B 的方案数
背包DP…… 太久没写了已经不会写了……
dp[n][m][b]表示当前为第 n个人,还剩 m行代码,b个可容许bug
然后无须枚举当前人写了几行代码,只需要从大到小枚举 m
然后把状态还是更新第 n个人上,就和普通的完全背包一样
所以总的复杂度是
(N3)
的
#pragma comment(linker, "/STACK:102400000,102400000")
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cctype>
#include <map>
#include <set>
#include <queue>
#include <bitset>
#include <string>
#include <complex>
using namespace std;
typedef pair<int,int> Pii;
typedef long long LL;
typedef unsigned long long ULL;
typedef double DBL;
typedef long double LDBL;
#define MST(a,b) memset(a,b,sizeof(a))
#define CLR(a) MST(a,0)
#define SQR(a) ((a)*(a))
#define PCUT puts("\n----------")
const int maxn=5e2+10;
int N,M,B,MOD;
int A[maxn], dp[2][maxn][maxn];
inline void Mod(int &x){if(x>=MOD) x-=MOD;}
int main()
{
#ifdef LOCAL
freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
#endif
while(~scanf("%d%d%d%d", &N, &M, &B, &MOD))
{
for(int i=1; i<=N; i++) scanf("%d", &A[i]);
CLR(dp);
dp[0][M][B] = 1;
for(int n=1,cur,las; n<=N; n++)
{
cur=n&1, las=(n-1)&1;
CLR(dp[cur]);
for(int m=M; m>=0; m--) for(int b=B; b>=0; b--)
{
dp[cur][m][b] += dp[las][m][b];
Mod(dp[cur][m][b]);
if(b>=A[n] && m)
{
dp[cur][m-1][b-A[n]] += dp[cur][m][b];
Mod(dp[cur][m-1][b-A[n]]);
}
}
}
int ans = 0;
for(int i=0; i<=B; i++)
{
ans += dp[N&1][0][i];
Mod(ans);
}
printf("%d\n", ans);
}
return 0;
}