台州 OJ 1315 Dividing 多重背包

题目的大概意思就是,有 6 种石头,价值分别是 1,2,3,4,5,6,给出他们的数量,求是否能将他们平分成两组价值相同的石头。

设石头的总价值为sum。把石头的价值看成重量,则问题转换成是否能恰好装下指定重量的石头,及背包容量为 sum/2 时,是否存在恰好装下一些石头的情况。

代码:

#include <iostream>
#include <cstring>
using namespace std;

const int MAX = 120005;

int dp[MAX];
int num[7];

//多重背包问题,背包的重量为 i,不考虑价值,只考虑是指定重量(所有重量的一半)可否到达。
//写出框架,再考虑剪枝
int main(){
    //freopen("input.txt", "r", stdin);
    int T = 0;
    while(1){
        bool isEnd = true;
        int sum = 0;
        for(int i=1; i<=6; i++){
            cin >> num[i];
            sum += i*num[i];
            if(num[i])
                isEnd = false;
        }
        if(isEnd){
            break;
        }

        cout << "Collection #" << ++T << ":" << endl;

        if(sum & 1){        //奇数不可能平分
            cout << "Can‘t be divided." << endl << endl;
            continue;
        }

        sum /= 2;
        memset(dp, 0, sizeof(dp));
        dp[0] = 1;        //初始状态,其他价值设为不可到达
        int maxValue = 0;    //可到达的最大价值 

        //DP
        for(int i=1; i<=6; i++){
            for(int j=maxValue; j>=0; j--){
                if(num[i] && dp[j]){    //如果前一个物品的 j 可到达,则从前一个物品在 j 的状态转移过来
                    for(int k=1; k<=num[i]; k++){    //从 j 状态出发,将所有可到达的状态标记
                        if(dp[j+k*i] == 1)            //后面的状态一定已经标记过了,因为 j 是递减的。
                            break;
                        dp[j+k*i] = 1;
                    }
                }
            }
            maxValue += i*num[i];    //可到达的最大价值增加
            if(maxValue >= sum)
                maxValue = sum;        //最大到目标价值就可以了,比目标价值大的不用考虑
        }

        if(dp[sum]){
            cout << "Can be divided." << endl << endl;
        }else{
            cout << "Can‘t be divided." << endl << endl;
        }
    }
} 
时间: 2024-10-17 15:22:02

台州 OJ 1315 Dividing 多重背包的相关文章

HDU 1059 Dividing(多重背包)

HDU 1059 Dividing(多重背包) http://acm.hdu.edu.cn/showproblem.php?pid=1059 题意: 现在有价值为1,2,3,4,5,6的6种物品, 它们的数量为num[i]( 1<=i<=6 )个. 现在要问的是能否把所有的的物品分成两份且这两份物品的价值总和相同 ? 分析: 首先我们求出所有物品的价值和sum_val, 如果sum_val是奇数, 那么明显不能分. 那么sum_val为偶时, 我们令m=sum_val/2. 我能只要看看从所有

POJ 1014 Dividing (多重背包)

Dividing Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 58921   Accepted: 15200 Description Marsha and Bill own a collection of marbles. They want to split the collection among themselves so that both receive an equal share of the marbl

poj1014+hdu1059--A - Dividing(多重背包,二进制优化)

A - Dividing Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Description Marsha and Bill own a collection of marbles. They want to split the collection among themselves so that both receive an equal share of

hdu 1059 Dividing(多重背包优化)

Dividing Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 20635    Accepted Submission(s): 5813 Problem Description Marsha and Bill own a collection of marbles. They want to split the collection

hdu(1059) Dividing(多重背包)

题意:输入六个数,价值分别为1——6,输入的数代表该价值的物品的个数:求能否平均分. key:如果奇数肯定不能分,直接输出答案.偶数的话,就是多重背包问题. 试过两种做法,第一种是背包九讲的二进制优化,写三个函数,分别是bag01, bagall, bagmulti~第二种是直接多重背包,但很可能tle,这题我交的就是tle了~ #include <iostream> #include <algorithm> #include <string.h> #include &

POJ 1014 / HDU 1059 Dividing 多重背包+二进制分解

Problem Description Marsha and Bill own a collection of marbles. They want to split the collection among themselves so that both receive an equal share of the marbles. This would be easy if all the marbles had the same value, because then they could

【POJ1014】Dividing 多重背包,二进制物品拆分转01背包

直接做01背包,即把物品数量累加,做20000物品的01背包指定TLE,不用我说了吧! 本文的优化是二进制优化,O(logn),至于完全背包记录已使用个数的O(n)算法本文不进行讲解,在博客的"背包"分类里. 二进制优化: 大家知道一个十进制数可以转换成二进制,那么假设某种物品有1023种,即2^10-1,二进制为111111111,则可以视为每一位分别是一个由{1,2,4,8,16,32,64,128,256,512}个物品糅合成的大物品,二进制数每一位0表示不取,1表示取,这样我们

Dividing 多重背包 倍增DP

Dividing 给出n个物品的价值和数量,问是否能够平分. 1 #include <iostream> 2 #include <cstring> 3 #include <cmath> 4 #include <cstdio> 5 #include <algorithm> 6 #include <vector> 7 #include <string> 8 #include <map> 9 #include <

poj1014 hdu1059 Dividing 多重背包

有价值为1~6的宝物各num[i]个,求能否分成价值相等的两部分. #include <iostream> #include <cstring> #include <string> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #include <queue> #include <map> #def