hdu 1171 Big Event in HDU
http://acm.hdu.edu.cn/showproblem.php?pid=1171
题目大意是n种东西,知道价值和数量。尽量分成两份,两份对应的价值,先输出大的,再输出小的。
可以转化01背包,也可以直接用多重背包做。
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define maxn 1300000 5 using namespace std; 6 7 int n; 8 int v[maxn],m[maxn]; 9 int dp[maxn]; 10 int vv; 11 int v1[maxn]; 12 13 void defZeroPack(int c,int w) 14 { 15 for(int i=vv; i>=c; i--) 16 { 17 dp[i]=max(dp[i],dp[i-c]+w); 18 } 19 } 20 21 void defCompletePack(int c,int w) 22 { 23 for(int i=c; i<=vv; i++) 24 { 25 dp[i]=max(dp[i],dp[i-c]+w); 26 } 27 } 28 29 void defMultiplePack(int c,int w,int cnt) 30 { 31 if(c*cnt>=vv) defCompletePack(c,w); 32 else 33 { 34 int k=1; 35 while(k<cnt) 36 { 37 defZeroPack(k*c,k*w); 38 cnt-=k; 39 k<<=1; 40 } 41 defZeroPack(cnt*c,cnt*w); 42 } 43 } 44 45 int main() 46 { 47 while(scanf("%d",&n)!=EOF) 48 { 49 if(n<0) break; 50 vv=0; 51 int t1=0; 52 for(int i=0; i<n; i++) 53 { 54 scanf("%d%d",&v[i],&m[i]); 55 vv+=v[i]*m[i]; 56 while(m[i]--) 57 { 58 v1[t1++]=v[i]; 59 } 60 } 61 memset(dp,0,sizeof(dp)); 62 /*for(int i=0; i<n; i++) 63 { 64 if(m[i]==1) defZeroPack(v[i],v[i]); 65 else 66 defMultiplePack(v[i],v[i],m[i]); 67 }*/ 68 for(int i=0; i<t1; i++) 69 { 70 for(int j=vv/2; j>=v1[i]; j--) 71 { 72 dp[j]=max(dp[j],dp[j-v1[i]]+v1[i]); 73 } 74 } 75 /*int u; 76 for(u=vv/2; u>=0; u--) 77 { 78 if(dp[u]==u) 79 { 80 break; 81 } 82 }*/ 83 printf("%d %d\n",vv-dp[vv/2],dp[vv/2]); 84 } 85 return 0; 86 }