hdu 1171 多重背包

题意:给出价值和数量,求能分开的最近的两个总价值,例如10,20*2,30,分开就是40,40

链接:点我

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<queue>
 7 #include<map>
 8 using namespace std;
 9 #define MOD 1000000007
10 const int INF=0x3f3f3f3f;
11 const double eps=1e-5;
12 typedef long long ll;
13 #define cl(a) memset(a,0,sizeof(a))
14 #define ts printf("*****\n");
15 const int MAXN=250010;
16 int n,m,tt;
17 int a[MAXN],b[MAXN];
18 int dp[MAXN];
19 
20 int nValue;
21 //0-1背包,代价为cost,获得的价值为weight
22 void ZeroOnePack(int cost,int weight)
23 {
24     for(int i=nValue;i>=cost;i--)
25         dp[i]=max(dp[i],dp[i-cost]+weight);
26 }
27 //完全背包,代价为cost,获得的价值为weight
28 void CompletePack(int cost,int weight)
29 {
30     for(int i=cost;i<=nValue;i++)
31         dp[i]=max(dp[i],dp[i-cost]+weight);
32 }
33 //多重背包
34 void MultiplePack(int cost,int weight,int amount)
35 {
36     if(cost*amount>=nValue)CompletePack(cost,weight);
37     else
38     {
39         int k=1;
40         while(k<amount)
41         {
42             ZeroOnePack(k*cost,k*weight);
43             amount-=k;
44             k<<=1;
45         }
46         ZeroOnePack(amount*cost,amount*weight);
47     }
48 }
49 int main()
50 {
51     int i,j,k;
52     #ifndef ONLINE_JUDGE
53     freopen("1.in","r",stdin);
54     #endif
55     while(scanf("%d",&n)!=EOF)
56     {
57         if(n<0) break;
58         nValue=0;
59         for(i=0;i<n;i++)
60         {
61             scanf("%d%d",&a[i],&b[i]);
62             nValue+=a[i]*b[i];
63         }
64         cl(dp);
65         for(i=0;i<n;i++)
66         {
67             MultiplePack(a[i],a[i],b[i]);
68         }
69         int v=nValue/2;
70         while(dp[v]!=v) v--;
71         printf("%d %d\n",nValue-v,v);
72     }
73 }

 

posted @ 2015-05-10 10:59  miao_a_miao  阅读(128)  评论(0编辑  收藏  举报