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 }
View Code

 

posted @ 2014-10-15 11:10  null1019  阅读(118)  评论(0编辑  收藏  举报