给定一个数组,求数组里面的值的和为某个值的方案总数(动态规划)
题目链接
题意
给定一个有n个正整数的数组A和一个整数sum,求选择数组A中部分数字和为sum的方案数。
当两种选取方案有一个数字的下标不一样,我们就认为是不同的组成方案。
思路
动态规划,设dp[n][m]是前n个数,和为m的总的方案数
那么如果第n个数不选,那么dp[n][m]=dp[n-1][m]
如果选择第n个数,那么dp[n][m]=dp[n-1][m-A[n]]
所以总的方案数为dp[n][m]=dp[n-1][m]+dp[n-1][m-A[n]]
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<string>
using namespace std;
long long dp[1010][1010];
long long a[1010];
int main(int argc, char** argv)
{
// freopen("in.txt", "r", stdin);
int n,sum;
scanf("%d %d",&n,&sum);//dp[n][m] 用n个数 求和得到sum的方案总数
for(int i=1;i<=n;i++) {
scanf("%d",&a[i]);
}
//边界条件 dp[i][0]=1;
for(int i=0;i<=n;i++){
dp[i][0]=1;
}
for(int i=1;i<=n;i++){
for(int j=0;j<=sum;j++){
// if(j>=a[i]) dp[i][j]+=dp[i-1][j-a[i]];//第i个数选或者不选
if(j>=a[i])
dp[i][j]=dp[i-1][j]+dp[i-1][j-a[i]];//不选a[i] + 选了a[i]的方案总数
else
dp[i][j]=dp[i-1][j];//一定不能选
}
}
// dp[1][a[1]]=1;
//
// for(int i=2;i<=n;i++){
// for(int j=1;j<i;j++){
//
// for(int k=sum;k>=a[j];k--){
// dp[i][k]+=dp[j][k-a[j]];
// }
// }
// }
//
printf("%lld\n",dp[n][sum]);
return 0;
}