首页 > 技术文章 > HDU-1171 Big Event in HDU

tooyoungtoosimple 2015-05-01 14:10 原文

简单的多重背包问题,要使设备的体积之和尽量均匀的分成两部分,设总体积为v2 则该问题就转化成了一个背包容量为v/2的多重背包问题

费用和价值都为设备的体积,根据num[i] * cost[i] 是否小于 v / 2转化为01背包和完全背包做

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<iomanip>
 5 #include<string>
 6 #define mem(a) memset(a, 0, sizeof(a))
 7 using namespace std;
 8 const int maxn = 60;
 9 double dp[260000];
10 int cost[maxn]; int num[maxn];
11 int main()
12 {
13     int n;
14     while(cin >> n && n > 0) {
15         int v = 0;
16         for(int i = 1 ; i <= n ; i++) cin >> cost[i] >> num[i], v += cost[i] * num[i];
17         int v1 = v; v /= 2;
18         mem(dp);
19         for(int i = 1 ; i <= n ; i++) { /// complete pack
20             if(cost[i] * num[i] >= v) {
21                 for(int j = 1 ; j <= v ; j++)
22                     if(j - cost[i] >= 0)
23                         dp[j] = max(dp[j], dp[j - cost[i]] + cost[i]);
24             }
25             else { /// zero one pack
26                 int k = 1;
27                 while(k <=num[i]) {
28                     for(int j = v ; j >= cost[i] * k ; j--) dp[j] = max(dp[j], dp[j - cost[i] * k] + cost[i] * k);
29                     num[i] -= k; k *= 2;
30                 }
31                 for(int j = v ; j >= cost[i] * k ; j--) dp[j] = max(dp[j], dp[j - cost[i] * k] + cost[i] * k);
32             }
33         }
34         cout << v1 - dp[v] << " " << dp[v] << endl;
35     }
36     return 0;
37 }

 

推荐阅读