用二维数组实现0-1背包就是填写一个二维数组,二维数组的最后一个元素即为背包实现的最大价值。
填写规则是:
(1)如果当前背包的重量小于第i个物品的重量时,此时不装第i个物品背包的最大价值即为只考虑前i-1个物品时的最大值。v[i-1][j]
(2)如果当时背包的重量大于或等于第i个物品的重量时,此时就要考虑到底要不要装第i个物品。就需要判断一下装上第i个物品是否比不装价值更大。就需要比较val[i-1]+v[i-1][j-weight[i-1]]和v[i-1][j]的大小,取最大值。
示例:
背包最大承重:10
物品重量 weight[]={5,4,6,3}
物品价值 value[]={10,40,30,50}
具体代码如下:
import java.util.*;
import java.math.*;
//使用二维数组的方法。
public class Knapsack{
public static void Knapsack1(int[] val,int[] weight,int w){
int n=weight.length;
int[][] v=new int[n+1][w+1];//二维矩阵
for(int col=0;col<w;col++){//填这个二维矩阵
v[0][col]=0;//第0行全为零
}
for(int row=0;row<=n;row++){
v[row][0]=0;//第0列全为零
}
for(int i=1;i<=n;i++){//列:物品数量
for(int j=1;j<=w;j++){//行:重量
//怎么判断第i个物品装还是不装呢。
if(weight[i-1]<=j){//如果当前物品的重量小于等于背包中的当前重量,就要判断第i个物品是否值得拿。
int val1=v[i-1][j];//如果第i件商品不拿就还是前i-1件商品的嘴的价值。
//第i件商品拿,就是第i件商品的价值加上背包剩余的最大价值
int val2=val[i-1]+v[i-1][j-weight[i-1]];
v[i][j]=Math.max(val1,val2);
}
else{//如果当前物品重量大于背包中的当前重量。
v[i][j]=v[i-1][j];//不放,直接使用前一行的最优解。
}
}
}
System.out.println("二维矩阵为:");
for(int i=0;i<=n;i++){
for(int j=0;j<=w;j++){
System.out.print(v[i][j]+" ");
}
System.out.println();
}
System.out.println("故背包可以装下物品的最大价值为"+v[n][w]);
}
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
System.out.println("请输入背包的最大承重");
int w=scanner.nextInt();
System.out.println("请输入物品的数量:");
int num=scanner.nextInt();
int[] weight=new int[num];
int[] val=new int[num];
System.out.println("请输入物品的重量:");
for(int i=0;i<num;i++){
weight[i]=scanner.nextInt();
}
System.out.println("请过输入物品的价值:");
for(int j=0;j<num;j++){
val[j]=scanner.nextInt();
}
Knapsack1(val,weight,w);
}
}
运行结果:
来源:https://blog.csdn.net/qq_40345846/article/details/102503151