ACM —— 1014 Dividing

解题代码:

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

}


 

猜你喜欢

转载自blog.csdn.net/WYYZ5/article/details/48681339