输入:
n=3
m=3
a={1,2,3}
M=10000
输出:
6 (0+0+3,0+1+2,0+2+1,1+0+2,1+1+1,1+2+0)
为了不重复计数,同一种类的物品最好一次性处理好.于是我们按照如下方式进行定义.
dp[i+1][j]=从前i种物品中取出j个的组合总数
复杂度:O(nm)
1 int n,m; 2 int a[MAX]; 3 4 int dp[MAX][MAX]; //数组 5 6 void solve() 7 { 8 //一个都不取的方法总是只有一种 9 for(int i=0; i<=n; i++){ 10 dp[i][0]=1; 11 } 12 for(int i=0; i<=n; i++){ 13 for(int j=1; j<=m; j++){ 14 if(j-1-a[i]>=0){ 15 //在有取余的情况下,要避免减法运算的结果出现负数 16 dp[i+1][j]=(dp[i+1][j-1]+dp[i][j]-dp[i][j-1-a[i]]+M)%M; 17 } 18 else{ 19 dp[i+1][j]=(dp[i+1][j-1]+dp[i][j])%M; 20 } 21 } 22 } 23 printf("%d ",dp[n][m]); 24 }