问题描述
有n个物品,它们有各自的体积和价值,现有给定容量的背包,如何让背包里装入的物品具有最大的价值总和?
public class knapsack {
public static void main(String[] args) {
int w[]={0,2,2,6,5,4};
int []v= {0,6,3,5,4,6};
int [][]m=new int[6][11];
int []x=new int[10];
int c=10;
System.out.println("装入商品的最大价值为");
Knapsack(v,w,c,m);
System.out.println("装入的商品为:");
traceback(m,w,c,x);
}
public static void Knapsack(int v[],int w[],int c,int [][]m)
{ int n=v.length-1;
int jMax = Math.min(w[n]-1,c);//以下填最后一行,要么填0,要么填v[n]
for(int j=0; j<=jMax;j++)
m[n][j]=0;
for(int j=w[n]; j<=c; j++)
m[n][j] = v[n];
for(int i=n-1; i>1; i--)
{ jMax =Math.min(w[i]-1,c);
for(int j=0; j<=jMax; j++)//背包剩余容量j<=jMax<c
m[i][j] = m[i+1][j]; //i没放,价值等于前
for(int j=w[i]; j<=c; j++) {
m[i][j] = Math.max(m[i+1][j],m[i+1][j-w[i]]+v[i]);//效益值增长vi
}
}
m[1][c] = m[2][c]; //下面填第一行最后一列
if(c>=w[1])
m[1][c] = Math.max(m[1][c],m[2][c-w[1]]+v[1]);
System.out.println(m[1][c]);
}
public static void traceback(int [][]m, int w[],int c,int []x)
{ int n=w.length-1;
for(int i=1; i<n; i++) //从m二维数组的右上角往下,如果与
{ if(m[i][c]==m[i+1][c] ) //下面一格等值,则第i个物品没放入
x[i]=0;
else
{
x[i]=1; //第i个物品放入
c=c-w[i];
System.out.println(w[i]);
}}
x[n]= (m[n][c]>0)?1:0; //第n个物品有没有放入
if(x[n]==1) {
System.out.println(w[n]);
}
}
}