package com.algorithm.背包问题;
public class BeiBaoProblem {
public static void main(String[] args){
int[] v = new int[]{6,3,5,4,6};
int[] w = new int[]{2,2,6,5,4};
int n = v.length, c = 10;
/*
* m的维数为(n+1)*(c+1)
*/
int[][] m = knapsack(v, w, c, n);
for(int i = 0; i <= n; i++){
for(int j = 0; j<= c; j++)
System.out.print(m[i][j]+" ");
System.out.println();
}
System.out.println("背包问题的最优解:"+m[n][c]);
System.out.println("背包容量:"+c);
int x[] = traceBack(m,w,c,n);
for(int k = 0; k < x.length; k++)
if(x[k] == 1)
System.out.println("第"+ (k+1) +"个物品 "+"(价值"+v[k]+"、重量"+w[k]+") 装入");
}
/**
*
* @param v 表示物品的价值
* @param w 表示物品的重量
* @param c 表示背包容量
* @param n 表示n种物品
* @param m 存储m(i,j)的值,表示背包容量为j,可选择物品为i,i+1,...,n时背包问题的最优解
*/
public static int[][] knapsack(int[] v, int[] w, int c, int n){
int[][] m = new int[n+1][c+1];
/*
* 背包容量为0的背包,不能装入第i个物品
*/
for(int i = 0; i < n+1 ; i++) m[i][0] = 0;
/*
* 背包容量为j的背包,不能装入前0个物品
*/
for(int j = 0; j < c+1; j++ ) m[0][j] = 0;
/*
* 分两种情况
*/
for(int i = 1; i < n+1; i++){
for(int j = 1; j < c + 1; j++)
/*
* 背包能够装入第i个物品,选择是否装入。取装入时,和不装入时的最大值
*/
if(w[i-1] <= j){
m[i][j] = Math.max(m[i-1][j], m[i-1][j-w[i-1]] + v[i-1]);
}else{
/*
* 不装入第i个物品
*/
m[i][j] = m[i-1][j];
}
}
return m;
}
public static int[] traceBack(int m[][],int[] w, int c, int n){
int[] x = new int[n+1];
for(int i = 1; i < n+1; i++)
if(m[i][c] == m[i-1][c]){
/*
*不装入第i个物品
*/
x[i-1] = 0;
}else{
/*
*装入第i个物品
*/
x[i-1] = 1;
/*
*背包容量减少w[i-1]
*/
c -= w[i-1];
}
return x;
}
}
运行效果:
0 0 0 0 0 0 0 0 0 0 0
0 0 6 6 6 6 6 6 6 6 6
0 0 6 6 9 9 9 9 9 9 9
0 0 6 6 9 9 9 9 11 11 14
0 0 6 6 9 9 9 10 11 13 14
0 0 6 6 9 9 12 12 15 15 15
背包问题的最优解:15
背包容量:10
第1个物品 (价值6、重量2) 装入
第2个物品 (价值3、重量2) 装入
第5个物品 (价值6、重量4) 装入