Big Event in HDU HDU1171
就是求一个简单的背包:
题意:就是给出一系列数,求把他们尽可能分成均匀的两堆
如:2 10 1 20 1 结果是:20 10。才最均匀!
三种解法:
多重背包的优化与否:(1031MS)
1 #include<iostream> 2 #include<stdio.h> 3 #include<algorithm> 4 #include<string.h> 5 using namespace std; 6 int dp[250005]; 7 int a[55],b[55]; 8 int main() 9 { 10 int n,s,i,j,k; 11 while(scanf("%d",&n)!=EOF) 12 { 13 if(n<0) 14 break; 15 s=0; 16 for(i=0;i<n;i++) 17 { 18 scanf("%d%d",&a[i],&b[i]); 19 s+=a[i]*b[i]; 20 } 21 memset(dp,0,sizeof(dp)); 22 for(i=0;i<n;i++) 23 for(j=1;j<=b[i];j++) 24 for(k=s/2;k>=a[i];k--) 25 dp[k]=max(dp[k],dp[k-a[i]]+a[i]); 26 if(dp[s/2]>s-dp[s/2]) 27 printf("%d %d ",dp[s/2],s-dp[s/2]); 28 else 29 printf("%d %d ",s-dp[s/2],dp[s/2]); 30 } 31 return 0; 32 }
二进制优化的:(46MS)
1 #include<iostream> 2 #include<algorithm> 3 #include<stdio.h> 4 #include<string.h> 5 using namespace std; 6 int dp[250005],a1[250005]; 7 int main() 8 { 9 int a[5005],b[5005],n,i,j,k,s,cout1; 10 while(scanf("%d",&n)!=EOF) 11 { 12 if(n<0) 13 break; 14 s=0; 15 cout1=0; 16 for(i=0;i<n;i++) 17 { 18 scanf("%d%d",&a[i],&b[i]); 19 s+=a[i]*b[i]; 20 for(k=1;k<=b[i];k<<=1) 21 { 22 a1[cout1++]=k*a[i]; 23 b[i]-=k; 24 } 25 if(b[i]>0) 26 a1[cout1++]=b[i]*a[i]; 27 } 28 memset(dp,0,sizeof(dp)); 29 for(i=0;i<cout1;i++) 30 for(j=s/2;j>=a1[i];j--) 31 dp[j]=max(dp[j],dp[j-a1[i]]+a1[i]); 32 if(dp[s/2]>=s-dp[s/2]) 33 printf("%d %d ",dp[s/2],s-dp[s/2]); 34 else 35 printf("%d %d ",s-dp[s/2],dp[s/2]); 36 } 37 return 0; 38 }
最后是母函数求解的:(875MS)
1 #include<iostream> 2 #include<stdio.h> 3 #include<algorithm> 4 #include<string.h> 5 using namespace std; 6 int c1[250005],c2[250005]; 7 int main() 8 { 9 int n,i,j,k,s; 10 int a[55],b[55]; 11 while(scanf("%d",&n)!=EOF) 12 { 13 s=0; 14 if(n<0) 15 break; 16 for(i=1;i<=n;i++) 17 { 18 scanf("%d%d",&a[i],&b[i]); 19 s+=a[i]*b[i]; 20 } 21 for(i=0;i<=s;i++) 22 { 23 c1[i]=0; 24 c2[i]=0; 25 } 26 c1[0]=1; 27 for(i=1;i<=n;i++) 28 { 29 for(j=0;j<=s;j++) 30 for(k=0;k+j<=s,k<=a[i]*b[i];k+=a[i]) 31 c2[k+j]+=c1[j]; 32 for(j=0;j<=s;j++) 33 { 34 c1[j]=c2[j]; 35 c2[j]=0; 36 } 37 } 38 for(i=s/2;i<=s;i++) 39 { 40 if(c1[i]!=0) 41 break; 42 } 43 if(i>=s-i)//且要取最大值 44 printf("%d %d ",i,s-i); 45 else 46 printf("%d %d ",s-i,i); 47 } 48 return 0; 49 }