* 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);
}