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;
    }
    
  • 相关阅读:
    【洛谷3527】[POI2011] MET-Meteors(树状数组+整体二分)
    【洛谷1580】yyy loves Easter_Egg I(字符串处理题)
    【BZOJ4866】[YNOI2017] 由乃的商场之旅(莫队)
    【BZOJ4810】[YNOI2017] 由乃的玉米田(莫队+bitset)
    【洛谷1494】[国家集训队] 小Z的袜子(莫队)
    【BZOJ3668】[NOI2014] 起床困难综合症(位运算思想)
    【BZOJ3720】Gty的妹子树(主席树+时间分块)
    【BZOJ2427】[HAOI2010] 软件安装(缩点+树形DP)
    【洛谷3648】[APIO2014] 序列分割(斜率优化DP)
    动态规划专题(五)——斜率优化DP
  • 原文地址:https://www.cnblogs.com/LSlzf/p/10804615.html
Copyright © 2011-2022 走看看