登 录
http://acm.hdu.edu.cn/showproblem.php?pid=1059
解题思路:给你6种价值不一样的东西,并且每种物品都有一定的数量,现在问你,你可以把他们平均分成两份价值一样的吗??
解题思路:多重背包问题
比较笨拙的代码
#include <stdio.h> #include <string.h> #include <math.h> #define Max(a,b) a>b?a:b #define Size 100005 int c[2*Size],w[2*Size],dp[200005]; int main() { int sum,i,num[7],no = 1,len,j,k,tem; while (1) { sum = 0; for (i=1;i<=6;i++) { scanf("%d",&num[i]); sum+=num[i]*i; } if(!sum) break; if(sum&1) else { len = 0; for (i=1;i<=6;i++) { /*二进制划分,转成01背包做*/ if(num[i]) { k =(int)(log(num[i]+1)/log(2))-1; for (j=0;j<=k;j++) { c[len] = w[len] = (int)(pow(2.0,j)*i); len++; } tem = (int)(pow(2.0,k+1))-1; if(num[i]!=tem) { c[len] = w[len] = (num[i]-tem)*i; len++; } } } for(i=0;i<=sum;i++) dp[i] = 0; for (i=0;i<len;i++) { for (j = sum/2;j>=c[i];j--) { dp[j] = Max(dp[j],dp[j-c[i]]+w[i]); } } if(dp[sum/2] == sum/2) printf("Collection #%d:/nCan be divided./n/n",no++); else printf("Collection #%d:/nCan't be divided./n/n",no++); } } return 0; }
参考背包问题后,学习的代码
#include <stdio.h> #include <string.h> #define Size 60005 #define Max(a,b) a>b?a:b int sum; int dp[Size]; /*01背包*/ void ZeroOnePack(int cost,int weight) { int i; for(i = sum;i>=cost;i--) dp[i] = Max(dp[i],dp[i-cost]+weight); } /*完全背包*/ void CompletePack(int cost,int weight) { int i; for(i=cost;i<=sum;i++) dp[i] = Max(dp[i],dp[i-cost]+weight); } /*多重背包*/ void MulPack(int cost,int weight,int count) { int i; if(cost*count>=sum) { CompletePack(cost,weight); return ; } i = 1; /*二进制划分*/ while (i<count) { ZeroOnePack(i*cost,i*weight); count-=i; i<<=1; } ZeroOnePack(count*cost,count*weight); } int main() { int num[7],no = 1,i; while (1) { sum = 0; for(i=1;i<=6;i++) { scanf("%d",&num[i]); sum+=num[i]*i; } if(!sum) break; if(sum&1) printf("Collection #%d:/nCan't be divided./n/n",no++); else { sum>>=1; for(i=0;i<=sum;i++) dp[i] = 0; for(i=1;i<=6;i++) if(num[i]) MulPack(i,i,num[i]); if(dp[sum] == sum) printf("Collection #%d:/nCan be divided./n/n",no++); else printf("Collection #%d:/nCan't be divided./n/n",no++); } } return 0; }
抱歉!评论已关闭.