Divided

*  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.
Input
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.
Output
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.
Sample Input
1 0 1 2 0 0 
1 0 0 0 1 1 
0 0 0 0 0 0 
Sample Output
Collection #1:
Can't be divided.

Collection #2:
Can be divided.

多重背包模板题,没有价值,即价值和重量相同,是否能平分则判断最后的dp[w/2]是否等于w/2;

import java.util.Scanner;
public class D_Dividing {
    static int c[]=new int[7];
    static int dp[]=new int[120005];
    static int W;
    static Scanner sc=new Scanner(System.in);
    static int count=0;
	public static void main(String[] args) {
		// TODO Auto-generated method stub
          while(sc.hasNext())
          {   count++;
              int flag=0;
              int capicity=0;
        	  for(int i=1;i<=6;i++)
        	  {
        		  c[i]=sc.nextInt();
        		  capicity+=c[i]*i;
        		  if(c[i]!=0) flag=1;
        	  }
        	  if(flag==0) break;
        	  if(capicity%2==1) 
        		  {
        		  System.out.println("Collection #"+count+":");
        		  System.out.println("Can't be divided.");
        		  System.out.println();
        		  continue;
        		  }
        	  W=capicity>>1;
        	  Arrays.fill(dp, 0);
              for(int i=1;i<=6;i++)
              {   
            	  MultiplePack(i,i,c[i]);
              }
              System.out.println("Collection #"+count+":");
              if(dp[W]==W) {
            	  System.out.println("Can be divided.");
            	  System.out.println();
              }
        	  else {
        		  System.out.println("Can't be divided.");
        		  System.out.println();
        	  }
            	  
//        	  for(int i=1;i<=6;i++)
//        		  for(int j=1;j<=capicity/2;j++)
//        			  { if(i<=j&&a[i]!=0)
//        				 {
//        				      if(dp[i-1][j]<dp[i][j-i]+i)
//        					  { dp[i][j]=dp[i][j-i]+i;
//        				        }
//        				      else
//        				      {
//        				    	  dp[i][j]=dp[i-1][j];
//        				      }
//        				  }
//        			      else
//        				  dp[i][j]=dp[i-1][j];
//        			  }
//        	  System.out.println("Collection #"+count+":");
//        	  if(dp[6][capicity/2]==capicity/2) 
//        		  System.out.println("Can be divided.");
//        	  else System.out.println("Can't be divided.");
//        	  System.out.println();
          }
	}
	private static void ZeroOnePack(int cost,int weight)
    {
    	for(int i=W;i>=cost;i--)
    	{   
    		dp[i]=Math.max(dp[i], dp[i-cost]+weight);
    	}
    }
private static void CompletePack(int cost,int weight)
{
	   for(int i=cost;i<=W;i++)
	   {
		   dp[i]=Math.max(dp[i], dp[i-cost]+weight);
	   }
}
private static void MultiplePack(int cost, int weight, int amount) {
	// TODO Auto-generated method stub
	
	if(cost*amount>=W)   
	{
		CompletePack(cost,weight);
		return;
	}
	int k=1;
	while(k<amount)
	{
		ZeroOnePack(k*cost,k*weight);
		amount-=k;
		k=k*2;
	}
	ZeroOnePack(amount*cost,amount*weight);
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值