解题代码:
DFS
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner stdin = new Scanner(System.in);
int[] num;
int count = 0;
while (true) {
count++;
num = new int[7];
int sum = 0;
for (int i = 1; i < 7; i ++) {
num[i] = stdin.nextInt();
sum += num[i]*i;
}
if (sum == 0) {
break;
}
if ((sum%2 == 0)&&dfs(sum/2, num, 6)) {
System.out.printf("Collection #%d:\n" , count);
System.out.println("Can be divided.\n");
} else {
System.out.printf("Collection #%d:\n" , count);
System.out.println("Can't be divided.\n");
}
}
}
private static boolean dfs(int value, int[] num, int pre) {
if (value == 0) {
return true;
}
for (int i = pre; i >= 1; i--) {
if (num[i] != 0) {
if ((value - i) >= 0) {
num[i]--;
if (dfs(value - i, num, i)) {
return true;
}
}
}
}
return false;
}
}
多重背包
import java.util.Arrays;
import java.util.Scanner;
public class Main {
private static int v;
private static int[] dp = new int[100000]; //状态数组
private static boolean flag;
public static void main(String[] args) {
Scanner stdin = new Scanner(System.in);
int[] n;
int count = 0;
while (true) {
count++;
n = new int[7];
int sum = 0;
for (int i = 1; i < 7; i ++) {
n[i] = stdin.nextInt();
sum += n[i]*i;
}
if (sum == 0) {
break;
}
if (sum%2 != 0) { //剪枝
System.out.printf("Collection #%d:\n" , count);
System.out.println("Can't be divided.\n");
continue;
}
v = sum/2;
flag = false;
Arrays.fill(dp, -1);
dp[0] = 0;
for (int i = 1; i <= 6; i++) {
MultiplePack(i,i,n[i]);
if (flag) { //剪枝
break;
}
}
if (flag) {
System.out.printf("Collection #%d:\n" , count);
System.out.println("Can be divided.\n");
} else {
System.out.printf("Collection #%d:\n" , count);
System.out.println("Can't be divided.\n");
}
}
}
/**
* 多重背包
*/
private static void MultiplePack(int cost, int weight, int amount) {
if (cost * amount >= v) {
CompletePack(cost,weight);
return;
}
if (flag) { //剪枝
return;
}
int k = 1;
while (k < amount) {
ZeroOnePack(k*cost,k*weight);
if (flag) { //剪枝
return;
}
amount -= k;
k *= 2;
}
ZeroOnePack(amount*cost,amount*weight);
}
/**
* 01背包
*/
private static void ZeroOnePack(int cost, int weight) {
for (int i = v; i >= cost; i--) {
dp[i] = Math.max(dp[i], dp[i-cost] + weight);
if (dp[i] == v) { //剪枝,当能够平分SumValue时退出
flag = true;
return;
}
}
}
/**
* 完全背包
*/
private static void CompletePack(int cost, int weight) {
for(int i = cost; i <= v; i++) {
dp[i] = Math.max(dp[i], dp[i-cost]+weight);
if (dp[i] == v) { //剪枝
flag = true;
return;
}
}
}
}