这道题自己想了两种方法:一种是搜索,代码很容易想到及理解
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