HDU 1171(完全背包)

题意:给一个数n,接下来n行,每行对应一个设备的两个值,第一个为设备的价值,第二个为该设备的数量。如何把所有设备一分为二,求两部分的价值总和尽量接近。

 

#include <cstdio>
#include <cstring>

int W[59], M[59];
int F[295000];
#define _max(a, b) ((a) > (b) ? (a) : (b))
int main()
{
    //freopen("1.txt", "r", stdin);
    //freopen("2.txt", "w", stdout);
    int n, i, s, ave;
    while (scanf("%d", &n) != EOF && n > 0)
    {
        for (s = i = 0; i < n; ++i)
            scanf("%d%d", W+i, M+i), s += M[i]*W[i];
        ave = s / 2;
        memset(F, 0, sizeof(int) * (ave+1));
        for (i = 0; i < n; ++i)
        {
            int k = 1;
            while (k < M[i])
            {
                for (int v = ave; v >= k*W[i]; --v)
                    F[v] = _max(F[v], F[v-k*W[i]]+W[i]*k);
                M[i] = M[i] - k;
                k = 2*k;
            }
            for (int v = ave; v >= M[i]*W[i]; --v)
                F[v] = _max(F[v], F[v-M[i]*W[i]]+W[i]*M[i]);
        }
        printf("%d %d\n", s - F[ave], F[ave]);
    }
    return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值