andre_joy

导航

hdu 1059

地址:http://acm.hdu.edu.cn/showproblem.php?pid=1059

题意:有价值为1,2,……,6的大理石各若干个,求是否能平分给两个人。

mark:看别人说多重背包,一直不知道在说什么。后来终于懂了,把总价值平分,往背包里放东西,如果最后恰好等于总价值的一半,那么就可以放进去。

   这个代码就当模版用了。。

代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int a[7], vmax;
int dp[120010];

int max(int a, int b) {return a > b ? a : b;}

void zero(int cost, int weight)   //01背包 
{
    int i;
    for(i = vmax; i >= cost; i--)
        dp[i] = max(dp[i], dp[i-cost]+weight);
}

void com(int cost, int weight)   //完全背包 
{
    int i;
    for(i = cost; i <= vmax; i++)
        dp[i] = max(dp[i], dp[i-cost]+weight);
}

void mut(int cost, int weight, int amount)   //多重背包 
{
    int i;
    if(cost*amount >= vmax) com(cost, weight);
    else
    {
        for(i = 1; i <= amount; i *= 2)
        {
            zero(i*cost, i*weight);
            amount -= i;
        }
        zero(amount*cost, amount*weight);
    }
}

int main()
{
    int i,j;
    j = 1;
    while(scanf("%d", &a[1]))
    {
        memset(dp, 0, sizeof(dp));
        vmax = a[1];
        for(i = 2; i < 7; i++)
        {
            scanf("%d", a+i);
            if(a[i] > 10) a[i] %= 10;
            vmax += i*a[i];
        }
        if(!vmax) break;
        printf("Collection #%d:\n", j++);
        if(vmax%2) {puts("Can't be divided.\n"); continue;}
        vmax /= 2;
        for(i = 1; i < 7; i++)
            mut(i, i, a[i]);
        if(dp[vmax] == vmax) puts("Can be divided.\n");
        else puts("Can't be divided.\n");
        
    }
    return 0;
}

 

posted on 2012-08-29 10:58  andre_joy  阅读(156)  评论(0编辑  收藏  举报