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;
    }
    
  • 相关阅读:
    【原理】【重点】异步回调的一些实现策略
    上下文传递
    洋码头全异步服务框架
    秒杀系统架构优化思路
    从urllib2的内存泄露看python的GC python引用计数 对象的引用数 循环引用
    jvisualvm All-in-One Java Troubleshooting Tool
    小心踩雷,一次Java内存泄漏排查实战
    django 请求处理流程 链路追踪
    存储过程
    Dijkstra's algorithm
  • 原文地址:https://www.cnblogs.com/LSlzf/p/10804615.html
Copyright © 2011-2022 走看看