NYOJ546 Divideing Jewels

这道题自己想了两种方法:一种是搜索,代码很容易想到及理解

 1 #include<stdio.h>
 2 int a[15];
 3 bool dfs(int n,int money){
 4     if(n==0||money==0){  //money==0的时候就可以跳出了,可以不必等n非要为0时跳出 
 5         if(money==0)
 6             return true;
 7     }else{
 8         for(int i=a[n];i>=0;i--)
 9             if(money>=n*i&&dfs(n-1,money-n*i)) return true; //刚开始忘了加 money>=n*i
10                                 //提交一直超时 
11     }
12     return false;
13 }
14 int main()
15 {
16     int i,sum,T=0;
17     while(1){
18         for(sum=0,i=1;i<=10;i++){
19             scanf("%d",&a[i]);
20             sum+=i*a[i];
21         }
22         if(sum==0) break;
23         if(sum&1) printf("#%d:Can't be divided.\n",++T); 
24         else{
25             if(dfs(10,sum>>1)) printf("#%d:Can be divided.\n",++T);
26             else printf("#%d:Can't be divided.\n",++T);
27         }
28     }
29     return 0;
30 }

二是用背包感觉应该是多重背包问题:

 1 #include<stdio.h>
 2 #include<string.h>
 3 const int INF=0x80000000;
 4 int a[10];
 5 bool f[100005];
 6 int main()
 7 {
 8     int i,j,k,sum,T=0;
 9     while(1){
10         for(sum=0,i=1;i<=10;i++){
11             scanf("%d",&a[i]);
12             sum+=i*a[i];
13         }
14         if(sum==0) break;
15         if(sum&1) printf("#%d:Can't be divided.\n\n",++T); 
16         else{
17             sum>>=1;
18             memset(f,0,sizeof(f));
19             f[0]=true;
20             for(i=1;i<=10;i++)  
21                 for(j=1;j<=a[i];j++) //这个是化成0-1背包求解的,
22                 //所以加了个这层循环,代表每种物品的个数,其实也就是把10件物品看成了总共sun(a[i])件物品 
23                 //这也就是所谓的多重背包 
24                     for(k=sum;k>=i;k--) //倒着推,因为看成是0-1背包 
25                         if(f[k-i]==true)
26                             f[k]=true;
27             if(f[sum]==true) printf("#%d:Can be divided.\n\n",++T); //检验能否推出f[sum]为true 
28             else printf("#%d:Can't be divided.\n\n",++T);
29         }
30     }
31     return 0;
32 }         
33         

 

posted on 2013-05-04 08:25  小花熊  阅读(451)  评论(0编辑  收藏  举报

导航