动态规划算法介绍
1.动态规划(Dynamic Programming)算法核心思想:大问题划分为小问题进行解决,从而一步步获取最优解的处理算法。
2.适用于动态规划求解的问题,经分解得到子问题往往不是相互独立的,即下一阶段的求解建立在上一个子阶段的基础上。
3.动态规划可以使用填表的方式逐步推出,得到最优解。
01背包问题
思路分析:
遍历第i个物品,根据w[i]和v[i]确定是否需要将物品放入背包中。
给定n个物品,设v[i] w[i]分别为第i个物品的价值和重量。
新的物品可以装入,则判断原来的价值 和 新物品+剩余空间最大价值 的max
遍历背包的每一磅j
①当v[i][0]=v[0][j]=0 //表格第一行和第一列为0
②当w[i]>j : v[i][j] = v[i-1][j] //准备加入的商品重量大于j的重量 使用上一次的装入策略
③当j >= w[i]时 :v[i][j] = max{v[i-1][j], v[i] + v[i-1][j-w[i]]} //准备加入的商品小于等于背包容量,
v[i-1][j]:上个背包最大值
v[i]:当前商品价值
v[i-1][j-w[i]]:装入i-1商品 到剩余空间j-w[i]的最大值
java实现:
public static void main(String[] args) {
int[] w = {1,4,3}; //物品重量
int[] val = {1500,3000,2000}; //物品价格 这里val[i] 就是 前面的v[i]
int m = 4; //背包容量
int n = val.length; //物品个数
//记录放入商品情况
int[][] path = new int[n+1][m+1];
//创建二维数组
//v[i][j] 表示前i个物品中能够装入容量为j的背包中的最大价值
int[][] v = new int[n+1][m+1];
//初始化第一行和第一列 默认也为0
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;
}
//动态规划处理
for(int i=1; i<v.length;i++){
for(int j =0; j <v[i].length; j++){
//公式
if(w[i-1] > j){ //程序从1开始 公式中的i - 1
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
if(v[i-1][j] < val[i-1] + v[i-1][j-w[i-1]]){
v[i][j] = val[i-1] + v[i-1][j-w[i-1]];
//记录当前情况
path[i][j] = 1;
}else{
v[i][j] = v[i-1][j];
}
}
}
}
for(int i=0; i<v.length;i++){
for(int j =0; j <v[i].length; j++){
System.out.print(v[i][j] + " ");
}
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--;
}
}

京公网安备 11010502036488号