http://icpc.upc.edu.cn/problem.php?cid=1682&pid=2
用f[i][j]表示在前i个位置摆j盆花的方案数,状态转移方程也就出来了:
f[i][j]=f[i-1][j-0]+f[i-1][j-1]+f[i-1][j-2]...+f[i-1][j-min(a[i],j)]
a[i]存第i种最多摆的花数。
然后显然需要三个循环,i,j同上,k从0到min(a[i],j),就是上面标蓝的数。
为什么是min(a[i],j)呢?因为你最多只能摆a[i]盆,再多就不行了。
#include<cstdio> #include<iostream> #include<cstdio> #define p 1000007 using namespace std; int a[1000],dp[1000][1000],n,m,i,j,k; int main() { scanf("%d%d",&n,&m); for(i=1; i<=n; i++) scanf("%d",&a[i]); for(i=0; i<=a[1]; i++) dp[1][i]=1; for(i=1; i<=n; i++) for(j=0; j<=m; j++) for(k=0; k<=min(j,a[i]); k++) dp[i][j]=(dp[i][j]+dp[i-1][j-k])%p; printf("%d\n",dp[n][m]); }