zoukankan      html  css  js  c++  java
  • [POJ 1014] Dividing

    问题描述

    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 just split the collection in half. But unfortunately, some of the marbles are larger, or more beautiful than others. So, Marsha and Bill start by assigning a value, a natural number between one and six, to each marble. Now they want to divide the marbles so that each of them gets the same total value. Unfortunately, they realize that it might be impossible to divide the marbles in this way (even if the total value of all marbles is even). For example, if there are one marble of value 1, one of value 3 and two of value 4, then they cannot be split into sets of equal value. So, they ask you to write a program that checks whether there is a fair partition of the marbles.

    输入格式

    Each line in the input file describes one collection of marbles to be divided. The lines contain six non-negative integers n1 , . . . , n6 , where ni is the number of marbles of value i. So, the example from above would be described by the input-line "1 0 1 2 0 0". The maximum total number of marbles will be 20000.
    The last line of the input file will be "0 0 0 0 0 0"; do not process this line.

    输出格式

    For each collection, output "Collection #k:", where k is the number of the test case, and then either "Can be divided." or "Can't be divided.".
    Output a blank line after each test case.

    样例输入输出

    样例输入

    1 0 1 2 0 0
    1 0 0 0 1 1
    0 0 0 0 0 0

    样例输出

    Collection #1:
    Can't be divided.

    Collection #2:
    Can be divided.

    题意概括

    给定六种硬币,第i种硬币的价值为i,输入每种硬币的数量ni,判断这些硬币能否分成价值相同的两组。

    解析

    首先,如果硬币的价值(sum)总数不是2的倍数,那么无论如何都无法分成价值相同的两组,直接输入即可。否则,每组的价值总数就是(sum/2)。那么问题就转化为已知硬币的数量和价值,从中选出一些硬币,问能否使这些硬币的价值综合为(sum/2)(如果一组为(sum/2),那么另一组也肯定为(sum/2))。这显然就可以用多重背包的方法来实现了。将这个背包的容积设为(sum/2),每个硬币的价值和体积都为自己的价值,最后只需要判断总体积为(sum/2)时总价值是否也为(sum/2)即可。

    另外,因为数量特别庞大,这里的多重背包需要使用二进制优化。

    代码

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #define N 1000000
    #define M 1000000
    using namespace std;
    int n,w,i,j,c[N],v[N],num[N],nc[N],nv[N],ncnt,sum,f[M],cnt;
    int main()
    {
    	for(i=1;i<=6;i++) c[i]=i;
    	while(1){
    		cnt++;
    		sum=ncnt=0;
    		memset(f,0,sizeof(f));
    		for(i=1;i<=6;i++){
    			cin>>num[i];
    			sum+=num[i]*i;
    		}
    		if(sum==0) break;
    		cout<<"Collection #"<<cnt<<":"<<endl;
    		if(sum%2==1){
    			cout<<"Can't be divided."<<endl<<endl;
    			continue;
    		}
    		else w=sum/2;
    		for(i=1;i<=6;i++){
    			int k;
    			for(k=1;num[i]-(1<<k)+1>0;k++){
    				ncnt++;
    				nc[ncnt]=(1<<(k-1))*c[i];
    			}
    			ncnt++;
    			k--;
    			nc[ncnt]=(num[i]-(1<<k)+1)*c[i];
    		}
    		for(i=1;i<=ncnt;i++){
    			for(j=w;j>=nc[i];j--){
    				f[j]=max(f[j],f[j-nc[i]]+nc[i]);
    			}
    		}
    		if(f[w]!=w) cout<<"Can't be divided."<<endl;
    		else cout<<"Can be divided."<<endl;
    		cout<<endl;
    	}
    	return 0;
    }
    
  • 相关阅读:
    《学习OpenCV》第一版课后习题解答
    【练习8.11】等级匹配cvMatchContourTrees、凸缺陷计算cvConvexityDefects
    支持与不支持in-place操作的OpenCV函数汇总
    【练习8.10】直接使用cvFindContour的结果图片和cvDrawContour的方式提取Hu矩,观察在图片缩放或旋转时的稳定性
    【练习8.7】cvGoodFeaturesToTrack确定图像强角点、cvFindCornerSubPix亚像素级角点检测
    【练习8.6】使用不同参数值观察cvFindDominantPoints寻找关键点的效果
    【练习8.5】轮廓长度计算机cvApproxPoly逼近
    【练习8.2】使用指定标志创建序列cvCreateSeq、在序列中插入元素
    【练习8.1】查找轮廓、寻找关键点cvFindDominantPoints、访问序列中的元素
    C或C++中struct内存对齐计算精简方案
  • 原文地址:https://www.cnblogs.com/LSlzf/p/10804615.html
Copyright © 2011-2022 走看看