HDU 1171 Big Event in HDU【多重背包】

大意:有n个物品,告诉你每个物品的价值问能否分成价值a、b两份使{a > b  && a + b == 总价值  && a - b尽量小}

分析:多重背包

代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 using namespace std;
 5 
 6 const int maxn = 55;
 7 const int INF = 1000000000;
 8 
 9 int n, sum;
10 int vo[maxn * maxn * 100];
11 int dp[maxn * maxn];
12 int solve() {
13     memset(dp, 0, sizeof(dp));
14     for(int i = 1; i < n; i++) {
15         for(int j = sum; j >= vo[i]; j--) {
16             dp[j] = max(dp[j], dp[j - vo[i]] + vo[i]);
17         }
18     }
19     int mid = (sum + 1) >> 1;
20     int i;
21     for(i = mid; i <= sum; i++) {
22         if(dp[i] == i) break;
23     }
24     return i;
25 }
26 
27 int main() {
28     int m;
29     int a, b;
30     while(scanf("%d",&m) ) {
31         if(m < 0) break;
32         n = 1;
33         sum = 0;
34         for(int i = 1; i <= m; i++) {
35             scanf("%d %d",&a, &b);
36             sum += a * b;
37             for(int k = 1; k <= b; k *= 2) {
38                 vo[n++] = k * a;
39                 b -= k;
40             }
41             if(b) vo[n++] = b * a;
42         }
43         int ans = solve();
44         printf("%d %d\n",ans, sum - ans);
45     }
46     return 0;
47 }
View Code

 

posted @ 2014-08-29 22:30  悠悠我心。  阅读(164)  评论(0编辑  收藏  举报