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

本文探讨了如何解决多重背包问题,通过分析并提供了一种有效的方法来将多个物品分成价值a、b两份,使得a大于b且a+b等于总价值,同时a-b尽可能小。

大意:有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

 

转载于:https://www.cnblogs.com/zhanzhao/p/3945830.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值