HDU 1171 Big Event in HDU——多重背包+二进制优化

版权声明:欢迎大家转载,转载请注明出处 https://blog.csdn.net/hao_zong_yin/article/details/79968842
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int INF = 0x3f3f3f3f;
int n, val[100], cnt[100], a[500];
bool dp[250000];
int iabs(int x) { return x > 0 ? x : -x; }
int main() {
    while (~scanf("%d", &n) && n > 0) {
        for (int i = 1; i <= n; i++) scanf("%d%d", &val[i], &cnt[i]);
        int m = 0, sum = 0;
        for (int i = 1; i <= n; i++) {
            sum += cnt[i]*val[i];
            int j = 0;
            while (cnt[i] >= (1<<j)) {
                a[++m] = (1<<j)*val[i];
                cnt[i] -= (1<<j);
                j++;
            }
            if (cnt[i] > 0) a[++m] = cnt[i]*val[i];
        }
        for (int i = 0; i <= sum; i++) dp[i] = false;
        dp[0] = true;
        for (int i = 1; i <= m; i++) {
            for (int j = sum; j >= a[i]; j--) {
                dp[j] = dp[j-a[i]];
            }
        }
        int ans = INF, ansa = 0, ansb = 0;
        for (int i = 0; i <= sum; i++) {
            if (!dp[i]) continue;
            if (iabs(sum-2*i) < ans) {
                ans = iabs(sum-2*i);
                ansa = i, ansb = sum - i;
            }
        }
        if (ansa < ansb) swap(ansa, ansb);
        printf("%d %d\n", ansa, ansb);
    }
    return 0;
}

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页