HDU 1171(完全背包)

来源:互联网 发布:java使用框架的好处 编辑:程序博客网 时间:2024/06/06 00:23

题意:给一个数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