HDU 1171 Big Event in HDU 多重背包

来源:互联网 发布:人工智能与国家安全 编辑:程序博客网 时间:2024/05/02 08:28

题目:

http://acm.hdu.edu.cn/showproblem.php?pid=1171

题意:

给定每种物品的价值和每种物品的数量,把物品分成两份,使这两份的价值只差最小,其中第一份的价值要大于等于第二份的

思路:

多重背包,物品的价值和重量都是原物品的价值。

#include <bits/stdc++.h>using namespace std;const int N = 300010;int dp[N];int v[110], num[110];int n;void ZeroOnePack(int w, int v, int W){    for(int i = W; i >= w; i--) dp[i] = max(dp[i], dp[i-w] + v);}void CompletePack(int w, int v, int W){    for(int i = w; i <= W; i++) dp[i] = max(dp[i], dp[i-w] + v);}void MultiplePack(int w, int v, int num, int W){    if(w * num >= W) CompletePack(w, v, W);    else    {        int k = 1;        while(k <= num)        {            ZeroOnePack(k*w, k*v, W);            num -= k;            k *= 2;        }        ZeroOnePack(num*w, num*v, W);    }}int main(){    while(scanf("%d", &n), n >= 0)    {        int W = 0;        for(int i = 1; i <= n; i++) scanf("%d%d", &v[i], &num[i]), W += v[i] * num[i];        memset(dp, 0, sizeof dp);        for(int i = 1; i <= n; i++)            MultiplePack(v[i], v[i], num[i], W/2);        int a = dp[W/2], b = W - a;        if(a < b) swap(a, b);        printf("%d %d\n", a, b);    }    return 0;}
0 0
原创粉丝点击