一、题目

2755:神奇的口袋

时间限制: 10000ms 内存限制: 65536kB
描述
有一个神奇的口袋,总的容积是40,用这个口袋可以变出一些物品,这些物品的总体积必须是40。John现在有n个想要得到的物品,每个物品的体积分别是a1,a2……an。John可以从这些物品中选择一些,如果选出的物体的总体积是40,那么利用这个神奇的口袋,John就可以得到这些物品。现在的问题是,John有多少种不同的选择物品的方式。
输入
输入的第一行是正整数n (1 <= n <= 20),表示不同的物品的数目。接下来的n行,每行有一个1到40之间的正整数,分别给出a1,a2……an的值。
输出
输出不同的选择物品的方式的数目。
样例输入
3
20
20
20
样例输出
3


二、分析

   尝试每种可能情况找出符合条件的
1、使用全局变量,递归法求解
2、动态规划法

三、AC源代码

 1、递归求解:

 1 #include <stdio.h>
2 int n,ans=0,type[20];
3 bool choose[20];
4
5 void dfs(int);
6 int sum();
7
8 int main()
9 {
10 int i;
11 scanf("%d",&n);
12 for(i=0;i<n;i++)
13 scanf("%d",&type[i]);
14 dfs(0);
15 printf("%d\n",ans);
16 return 0;
17 }
18
19 void dfs(int b)
20 {
21 if(b==n)
22 {
23 if(sum()==40)
24 ans++;
25 return;
26 }
27 else
28 {
29 choose[b]=false;
30 dfs(b+1);
31 choose[b]=true;
32 dfs(b+1);
33 }
34 }
35
36 int sum()
37 {
38 int i,s=0;
39 for(i=0;i<n;i++)
40 if(choose[i])
41 s+=type[i];
42 return s;
43 }

2、动态规划:

 1 #include<stdio.h>
2 #include<string.h>
3 int main()
4 {
5 int n,i;
6 int num[50],a[30];
7 scanf("%d",&n);
8 for(i=0;i<n;i++)
9 scanf("%d",&a[i]);
10 memset(num,0,sizeof(num));
11 for(i=0;i<n;i++)
12 {
13 int k=40-a[i];
14 while(k>=0)
15 {
16 if(num[k]>0)
17 num[k+a[i]]+=num[k];
18 k--;
19 }
20 num[a[i]]++;
21 }
22 printf("%d\n",num[40]);
23 return 0;
24 }





posted on 2011-12-18 21:01  小狗狗ACM  阅读(1545)  评论(0编辑  收藏  举报