水题 居然遇到杭电oj挂了==这是都在备战区域赛???
/************ hdu1711 2015.10.16 ************/ #include <iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int dp[50005]; int value[60],num[60]; int n,total,sum; void zero(int cost,int weight) { for(int i=total;i>=cost;i--) dp[i]=max(dp[i],dp[i-cost]+weight); } void complete(int cost,int weight) { for(int i=cost;i<=cost;i++) dp[i]=max(dp[i],dp[i-cost]+weight); } void multi(int cost,int weight,int cnt) { if(total<=cnt*cost) { complete(cost,weight); return; } int k=1; while(k<=cnt) { zero(k*cnt,k*weight); cnt=cnt-k; k=2*k; } zero(cnt*cost,cnt*weight); } int main() { while(~scanf("%d",&n)) { if(n==-1) break; total=0; sum=0; for(int i=0;i<n;i++) { scanf("%d%d",&value[i],&num[i]); total+=(value[i]*num[i]); } printf("%d \n",total); sum=total; total/=2; memset(dp,0,sizeof(dp)); for(int i=0;i<n;i++) { multi(value[i],value[i],num[i]); } printf("%d %d\n",sum-dp[total],dp[total]); } return 0; }
还有一种01背包的解法 感觉更适合这个题
之前WA了好多次 脑残错误都改过来了 依旧不对 重新写一遍果然好使
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int n,tot,a,b,sum; int dp[255000],val[600]; int main() { while(~scanf("%d",&n),n>0) { sum=0; tot=0; for(int i=0;i<n;i++) { scanf("%d%d",&a,&b); while(b--) { val[tot++]=a; sum+=a; } } memset(dp,0,sizeof(dp)); for(int i=0;i<tot;i++) { for(int j=sum/2;j>=val[i];j--) { dp[j]=max(dp[j],dp[j-val[i]]+val[i]); } } printf("%d %d\n",sum-dp[sum/2],dp[sum/2]); } return 0; }