杭电OJ 1059:Dividing

43 篇文章 0 订阅
15 篇文章 0 订阅

这个题目首先应该判断综合是否为偶数,如果不为偶数则不可分,如果为偶数则做进一步的分析。这是一道和背包有关的问题,由于是多重背包,所以需要进行转化,因为本题的数据量交大,所以不可以采用单个划分的形式,应该采用二进制划分,比如13可以分为1、2、4、6四个背包,这四个数字可以组成1-13中的任何数字。具体的做法请参考下面的代码:

#include <iostream>
#include <stdio.h>
#include <memory.h>
using namespace std;

const int N = 6;
int V, total, sum;
int bag[120005];
int w[15], n[15], v[1005];


int main()
{
    int i, temp,j, zz = 1;
    while(scanf("%d %d %d %d %d %d", &n[0], &n[1], &n[2], &n[3], &n[4], &n[5]))
    {
        if(n[0] + n[1] + n[2] + n[3] + n[4] + n[5] == 0) break;
        printf("Collection #%d:\n", zz++);
        V = 0;
        for(i = 0; i < N; i++)
        {
            w[i] = i + 1;
            V += w[i]*n[i]; //求总和
        }
        if(V%2 == 1)    //总和是奇数则不能平分
        {
            printf("Can't be divided.\n\n");
            continue;
        }
        sum = V/2; total = 0;
        for(i = 0; i < N; i++)  //二进制压缩为——01背包
        {
            if(n[i] == 0) continue;
            temp = 1;
            while(n[i] > temp)
            {
                v[total++] = temp*w[i]; //将新的值赋给v[]
                n[i] -= temp;
                temp *= 2;
            }
            v[total++] = n[i]*w[i];
        }
        memset(bag, 0, sizeof(bag));
        for(i = 0; i < total; i++)
        {
            for(j = sum; j >= v[i]; j--)
            {

                bag[j] =bag[j]>(bag[j-v[i]]+v[i])?bag[j]:(bag[j-v[i]]+v[i]);
            }
        }
        if(bag[sum] != sum)
            printf("Can't be divided.\n\n");
        else
            printf("Can be divided.\n\n");
    }

    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值