Big Event in HDU(HDU1171)可用背包和母函数求解

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\n",dp[s/2],s-dp[s/2]);
28         else
29             printf("%d %d\n",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\n",dp[s/2],s-dp[s/2]);
34         else
35             printf("%d %d\n",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\n",i,s-i);
45         else
46         printf("%d %d\n",s-i,i);
47     }
48     return 0;
49 }

 

posted on 2013-08-30 17:06  ~~碾压机  阅读(172)  评论(0编辑  收藏  举报