HDU-1171 Big Event in HDU 背包

通过给定的数据组成可及的状态。最后再中中间开始遍历所有可及的状态。就是一个完全背包,用二进制优化。

代码如下:

#include <cstdlib>
#include <cstdio>
#include <cstring>
#define MAXN 250005
using namespace std;
int N, dp[MAXN], p[55], n[55], total;

void zobag(int x) 
{
    for (int i = total>>1; i >= x; --i) {
        if (dp[i-x]) {
            dp[i] = 1;
        }
    }
}

void DP()
{ 
    for (int i = 0; i < N; ++i) {
        int k = 1;
        while (k <= n[i]) {
            zobag(p[i]*k);
            k <<= 1;
        }
        zobag(p[i]*(n[i]-(k>>1)));
    }
}

int main()
{
    while (scanf("%d", &N), N >= 0) {
        total = 0;
        memset(dp, 0, sizeof (dp));
        dp[0] = 1;
        for (int i = 0; i < N; ++i) {
            scanf("%d %d", &p[i], &n[i]);
            total += p[i]*n[i];
        } 
        DP();
        for (int i = total>>1; i >= 0; --i) {
            if (dp[i]) {
                printf("%d %d\n", total-i, i);
                break;
            }
        }
    }
    return 0; 
} 
posted @ 2012-04-19 16:45  沐阳  阅读(268)  评论(0编辑  收藏  举报