0-1背包问题之动态规划策略解决
/**
* 2."0-1"背包问题的动态规划算法
*/
package algorithm2;
public class Pack02 {
/**
* v[]代表物体的价值,w[]代表物体的重量,c代表包的容量,<br>
* m[i][j]表示i~n个物品背包容量为j的最大价值<br>
*
* @param v
* @param w
* @param c
* @param m
*/
public static void knapsack(int[] v, int[] w, int c, int[][] m) {
int n = v.length - 1;
//System.out.println(n);
//System.out.println(w[n]);
int jmax = Math.min(w[n] - 1, c);//jmax表示剩余重量且一个比w[n]小1的值,从1-jmax都无法装入包中
//System.out.println(jmax);
for (int j = 0; j < jmax; j++) {
m[n][j] = 0; // 当w[n]>j有m[n][j]=0
// System.out.println(m[n][0]+" "+m[n][1]+" "+m[n][2]+" "+m[n][3]);
}
// m[n][j]表示只有第n个物体时,背包的容量为j时最大价值
for (int i = w[n]; i <= c; i++)
{
m[n][i] = v[n]; // 当w[n]<=j有m[n][j]=v[n]
//System.out.print(m[n][i]+" ");
}
//System.out.println();
// (先求出只装入最后一个物体价值--上面的两个for循环)至底向上递归调用求出m[][]其他值,直到求出m[0][c]
for (int i = n - 1; i >= 1; i--) {
jmax = Math.min(w[i] - 1, c);
for (int k = 0; k <= jmax; k++)
m[i][k] = m[i + 1][k]; //表示没有装入下一个物体的情况
for (int h = w[i]; h <= c; h++) { //从最后一个物体开始往前装物体
m[i][h] = Math.max(m[i + 1][h], m[i + 1][h - w[i]] + v[i]);
//System.out.print(m[i][h]+" ");
}
}
//System.out.println();
m[0][c] = m[1][c];
//System.out.println(m[1][c]);
if (c >= w[0]) //判断装没装第一个物体
m[0][c] = Math.max(m[0][c], m[1][c - w[0]] + v[0]);
System.out.println("bestw==" + m[0][c]);
}
public static void traceback(int[][] m, int[] w, int c, int[] x) {
// 根据最优值求出最优解
int n = w.length - 1;
for (int i = 0; i < n; i++)
if (m[i][c] == m[i + 1][c])
x[i] = 0;
else {
x[i] = 1;
c -= w[i];
}
x[n] = (m[n][c] > 0) ? 1 : 0;
}
public static void main(String[] args) {
int[] wi = { 2, 4, 6, 5, 2 };
int[] vi = { 6, 4, 3, 5, 2 };
int[][] m = new int[11][11]; //11*11的二维数组保存结果
knapsack(vi, wi, 10, m);
int[] xi = new int[wi.length];
traceback(m, wi, 10, xi);
for (int i = 0; i < xi.length; i++)
System.out.print(" " + xi[i]);
}
}