1 //法一 :递归 把物品数目n和物品体积数组a[100]设为全局变量;
2 //count(i,sum)表示从数组的第i个数开始往后统计的组合数和为sum的种类数,
3 //sum为组合数的和,则:cout(i,sum)=cout(i+1,sum-a[i])+cout(i+1,sum),
4 //其中cout(i+1,sum-a[i])表示包含了a[i],即为从第i+1个数开始往后统计
5 //组合数的和为sum-a[i]的种类数, 而cout(i+1,sum)表示不包含a[i], 即为从第i+1个数开始往后统计组合数的和为sum的种类数 ***********************************
6 #include<iostream>
7 using namespace std;
8
9 int a[100];
10 int n=1;
11 int count(int i,int sum) {
12 if(sum==0) {
13 return 1; //找到一组和为sum的组合数;
14 }
15 if(i==n||sum<0) return 0;//i==n说明没有其他的数来组合,sum<0说明组合不出;
16 return count(i+1,sum-a[i])+count(i+1,sum);//从数组的第i为开始,包含a[i],和不包含;
17 }
18
19 int main() {
20 while(cin>>n) {
21 for(int i=0; i<n; i++)
22 cin>>a[i];
23 cout<<count(0,40)<<endl;
24 }
25 return 0;
26 }
1 //法二:动态规划
2 #include<iostream>
3 using namespace std;
4 #define N 100
5 int n,a[N];
6 int main() {
7 while(cin>>n) {
8 int (*dp)[50]=new int[N][50];//dp[i][j]表示从前i个物品中凑出体积j;
9 for(int i=1; i<=n; i++) {
10 cin>>a[i];
11 dp[i][0]=1; //初始边界
12 }
13 dp[0][0]=1;
14 for(int i=1; i<=n; i++)
15 for(int j=1; j<=40; j++) {
16 dp[i][j]=dp[i-1][j];
17 if(a[i]<=j)
18 dp[i][j]+=dp[i-1][j-a[i]];
19 }
20 cout<<dp[n][40]<<endl;
21 delete []dp;
22 }
23 return 0;
24 }