java动态规划实现01背包问题
java动态规划实现01背包问题
代码实现
/**
* 动态规划解决01背包问题
*/
public class Bag {
public static void main(String[] args) {
// 重量和价值
int[] w = {1, 4, 3};
int[] val = {1500, 3000, 2000};
// 背包容量
int m = 4;
// 物品个数
int n = val.length;
// 定义一个二维数组,记录存放情况
int[][] path = new int[n + 1][m + 1];
// 创建二维数组,表示表
int[][] v = new int[n + 1][m + 1];
// 初始化第一行、第一列
for (int i = 0; i < v.length; i++) {
v[i][0] = 0;
}
for (int i = 0; i < v[0].length; i++) {
v[0][i] = 0;
}
// 动态规划处理(不处理没物品行和0重量列)
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];
} else {
// 可以放的下时
// 用上一次的最优和这一次能放的最大值比较
// v[i][j] = Math.max(v[i - 1][j], (val[i - 1] + v[i - 1][j - w[i - 1]]));
// 为了记录存放记录,我们用if-else替代
// 拿到上次的最优
int lastBest = v[i - 1][j];
// 拿到这次最优
int thisTimeBest = (val[i - 1] + v[i - 1][j - w[i - 1]]);
if (lastBest < thisTimeBest) {
// 把当前情况记录下来
v[i][j] = thisTimeBest;
path[i][j] = 1;
} else {
v[i][j] = lastBest;
}
}
}
}
// 遍历结果
for (int[] ints : v) {
for (int i : ints) {
System.out.print(i + "\t");
}
System.out.println();
}
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;
}
}
}