算法競賽入門經典 例題9-5 0-1 揹包

/*算法競賽入門經典 例題 9-5 0-1揹包問題
 * f(i,j) 表示 “把前i個物品裝到容量爲j的揹包的最大總重量”
 * f(i,j) = max{f(i-1,j),f(i-1,j-v[i])+w(i)}
 * n 表示物品個數  c表示物品容量
 * */
import java.util.Scanner;

public class Package01 {

	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		int n = scanner.nextInt();// 物品個數
		int[] v = new int[n + 1]; // v[i]物品i的體積
		int[] w = new int[n + 1];// w[i] 物品i的重量
		int c = scanner.nextInt();// 容器容量
		int[][] f = new int[n + 1][c + 1];
		int[][] max = new int[n + 1][c + 1];
		for (int i = 1; i <= n; i++) {
			v[i] = scanner.nextInt();
			w[i] = scanner.nextInt();
			for (int j = 0; j <= c; j++) {
				f[i][j] = (i == 1 ? 0 : f[i - 1][j]);// f[1][j]默認就是0 這裏是爲了強調
				if (j >= v[i]) {
					if (f[i][j] < f[i - 1][j - v[i]] + w[i]) {
						f[i][j] = f[i - 1][j - v[i]] + w[i];
						max[i][j] = 1;
					}
				}
			}
		}
		System.out.println(f[n][c]);
		// 遞歸打印
		Package01 p = new Package01();
		p.print(max, n, c, f, w, v);
		System.out.println();
		// 遞推打印
		int m = f[n][c];
		int i = n, j = c;
		while (m > 0) {
			if (max[i][j] == 1) {
				System.out.printf("%d ", w[i]);
				m -= w[i];
				j -= v[i];
				i--;
			} else {
				i--;
			}
		}
	}

	private void print(int[][] max, int i, int j, int[][] f, int[] w, int[] v) {
		if (i == 0)
			return;
		if (max[i][j] == 1) {
			System.out.printf("%d ", w[i]);
			print(max, i - 1, j - v[i], f, w, v);
		} else {
			print(max, i - 1, j, f, w, v);
		}
	}
}

發佈了65 篇原創文章 · 獲贊 0 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章