1.需求:在可容纳重量最多4磅的背包中,所能够装入的最大价值是多少。所装入的东西不能重复,即所谓的01.
商品对应的重量和价值:
2.思路:
w[i]:表第i个物品的重量
v[i]:表物品的价值
v[i][j]:在前i个物品中,能够装入的容量为j的背包中的最大价值
每次遍历到第i个元素,根据w[i]的值决定要不要放进去。
所以;
1.当v[i][0]=v[0][j]=0;
2.当w[i]>j:v[i][j]=v[i-1][j];
3.当j>=w[i],v[i][j]=v[i-1][j]+v[][]
代码:
package com;
import java.util.Arrays;
public class KnapsackProblem {
public static void main(String[] args) {
//
int []w={1,4,3}; //物品的重量
int []val={1500,3000,2000}; //物品的价值
int n=val.length; //物品的个数
int m=4; //背包的容量
//创建二维数组,v[i][j]表示:前i个物品中能够装入容量为j的背包中年的最大价值
int [][]v=new int[n+1][m+1]; //第一行第一列为0 即物品为0或背包容量为0时都是0
//为了记录商品的情况,创建一个二维数组
int [][]path=new int[n+1][m+1];
//开始动态规划处理
for(int i=1;i<v.length;i++){
for(int j=1;j<v[0].length;j++){
if(w[i-1]>j){
v[i][j]=v[i-1][j]; //v[i-1]这个代表的是val,val是从0开始的,所以这里需要减1
}else{
//所以这里的v[i-1]对应到val那里就是val[i]
//v[i][j]=Math.max(v[i-1][j],val[i-1]+v[i-1][j-w[i-1]]);
//为了记录商品存放到背包的情况,就需要确定他到底走的是那一路,使用if-else来体现
if(v[i-1][j]<v[i-1][j-w[i-1]]+val[i-1]){
v[i][j]=v[i-1][j-w[i-1]]+val[i-1];
//把当前情况记录
path[i][j]=1;
}else{
v[i][j]=v[i-1][j];
}
}
}
}
for(int[] a:v){
System.out.println(Arrays.toString(a));
}
System.out.println("--------------------");
//倒着遍历(实际上就是分析了最后一种情况)
int i=path.length-1; //行的最大下标
int j=path[0].length-1; //列的最大下标
while(i>0&&j>0){
if(path[i][j]==1){
System.out.printf("第%d个商品放入背包\n",i);
j-=w[i-1];
}
i--;
}
}
}
运行结果: