http://blog.csdn.net/slowlight93/article/details/45578197原文连接
cf 543Ahttp://codeforces.com/problemset/problem/543/A
首先考虑最直接的三维方程
dp(i, j, k) 表示前i个程序员写了j行代码bug不超过kdp(i,j,k)=∑dp(i−1,j−r,k−r∗a[i]),第i个程序员写了r行代码
我们可以换种视角优化这个方程
1)第i个程序员没写代码
2)第i个程序员写了至少一行
dp(i,j,k)=dp(i−1,j,k)+dp(i,j−1,k−a[i])
这个方程在时间复杂度上已经是O(n^3)了
如果我们在储存的时候省掉第一维
那么在枚举到 (i, j, k)这个状态的时候实际储存的是 (i-1, j, k)
那么
dp(j, k) = dp(j, k) + dp(j-1, k-a[i])
最后附上代码
#include <algorithm>
#include <cstdio>
#include <iostream>
using namespace std;
int a[501];
int dp[501][501];
int main(void)
{
//freopen("in.txt","r",stdin);
int n,m,b,mod;
cin >> n >> m >> b >> mod;
for(int i = 1;i<=n;i++)
scanf("%d",&a[i]);
dp[0][0]=1;
int x =0;
for(int i = 1;i<=n;i++)
{
for(int j=1;j<=m;j++)
for(int t=a[i];t<=b;t++)
dp[j][t]=(dp[j][t]+dp[j-1][t-a[i]])%mod;
}
for(int i = 0;i<=b;i++)
x=(dp[m][i]+x)%mod;
cout << x << endl;
}