首页 > 编程语言 >动态规划算法

动态规划算法

时间:2022-10-01 10:33:38浏览次数:51  
标签:背包 val int 算法 length 物品 path 动态 规划

  • 应用实例
有一个背包,容量为4磅,现在将如下商品装入背包,要求装入的背包的总价值最大,并且重量不超出,且物品不能重复

# 当前为01背包
# 如果为完全背包则放入物品可重复

动态规划算法_i++

  • 简介
  • 动态规划算法_初始化_02

  • 思路分析
每次遍历到的第i个物品,根据w[i]和v[i]来确定是否需要将该物品放入背包中。
即对于给定的n个物品,设v[i]、w[i]分别为第i个物品的价值和重量,C为背包的容量。
再令v[i][j]表示在前i个物品中能够装入容量为j的背包中的最大价值。则我们有下面的结果:
(1) v[i][0]=v[0][j]=0; //表示 填入表 第一行和第一列是0
(2) 当w[i]> j 时:v[i][j]=v[i-1][j] // 当准备加入新增的商品的容量大于 当前背包的容量时,就直接使用上一个单元格的装入策略
(3) 当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]的最大值
当j>=w[i]时: v[i][j]=max{v[i-1][j], v[i]+v[i-1][j-w[i]]}

红色箭头指向 表示背包的容量
绿色箭头指向 表示当前拥有的物品

动态规划算法_二维数组_03

  • 代码实现
public class KnapsackProblem {

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; //物品的个数

//创建二维数组,
//v[i][j] 表示在前i个物品中能够装入容量为j的背包中的最大价值
int[][] v = new int[n+1][m+1];
//为了记录放入商品的情况,我们定一个二维数组
int[][] path = new int[n+1][m+1];

//初始化第一行和第一列, 这里在本程序中,可以不去处理,因为默认就是0
for(int i = 0; i < v.length; i++) {
v[i][0] = 0; //将第一列设置为0
}
for(int i=0; i < v[0].length; i++) {
v[0][i] = 0; //将第一行设置0
}

//根据前面得到公式来动态规划处理
for(int i = 1; i < v.length; i++) { //不处理第一行 i是从1开始的
for(int j=1; j < v[0].length; j++) {//不处理第一列, j是从1开始的
//公式
if(w[i-1]> j) { // 因为我们程序i 是从1开始的,因此原来公式中的 w[i] 修改成 w[i-1]
v[i][j]=v[i-1][j];
} else {
//说明:
//因为我们的i 从1开始的, 因此公式需要调整成
//v[i][j]=Math.max(v[i-1][j], val[i-1]+v[i-1][j-w[i-1]]);
//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
path[i][j] = 1;
} else {
v[i][j] = v[i - 1][j];
}

}
}
}

//输出一下v 看看目前的情况
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 ) { //从path的最后开始找
if(path[i][j] == 1) {
System.out.printf("第%d个商品放入到背包\n", i);
j -= w[i-1]; //w[i-1]
}
i--;
}

}

}



标签:背包,val,int,算法,length,物品,path,动态,规划
From: https://blog.51cto.com/chniny/5728148

相关文章

  • 非递归的方式实现二分查找算法
    简介二分查找法的运行时间为对数时间O(㏒₂n),即查找到需要的目标位置最多只需要㏒₂n步,假设从[0,99]的队列(100个数,即n=100)中寻到目标数30,则需要查找步数为㏒₂100,即最......
  • 【动态规划】背包问题----完全背包
    题目描述acwing完全背包要点1.每种物品可选无数次2.总体积不超过V3.总价值最大分析按照第i个物品选几个将集合进行划分第i种物品1件物品都不选f[i-1][j]第i......
  • React面试:谈谈虚拟DOM,Diff算法与Key机制
    1.虚拟dom原生的JSDOM操作非常消耗性能,而React把真实原生JSDOM转换成了JavaScript对象。这就是虚拟Dom(VirtualDom)每次数据更新后,重新计算虚拟Dom,并和上一次生成的虚拟......
  • LeetCode 无重复字符的最长子串算法题解 All In One
    LeetCode无重复字符的最长子串算法题解AllInOnejs/ts实现无重复字符的最长子串无重复字符的最长子串原理图解滑动窗口"usestrict";/****@authorx......
  • 【动态规划】背包问题----01背包
    题目描述acwing01背包要点1.每件物品只能使用一次2.总体积不超过V3.总价值最大分析按照集合划分最后一个不选i代表要从1到i-1中选择物品,并且其体积不超......
  • Python基本算法实现及总结归纳
    @目录冒泡排序快速排序插入排序选择排序希尔排序归并排序各个算法的时间复杂度附:二分法冒泡排序这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端(......
  • Even Number Addicts - 题解【动态规划/记忆化搜索】
    题面本题是CodeforcesGlobalRound22的C题。原题链接见:C.EvenNumberAddicts。下面搬运一下题面:DescriptionAliceandBobareplayingagameonasequence\(a_......
  • 传统优化方法:枚举法、启发式算法和搜索算法
    1.枚举法枚举出可行解集合内的所有可行解,以求出精确最优解。对于连续函数,该方法要求先对其进行离散化处理,这样就可能因离散处理而永远达不到最优解。当枚举空间比较大时......
  • PTA 21级数据结构与算法实验5—树和二叉树
    目录7-1还原二叉树7-2朋友圈7-3修理牧场7-4玩转二叉树7-5根据后序和中序遍历输出先序遍历7-6完全二叉树的层序遍历7-7列出叶结点7-8部落7-9建立与遍历二叉树7-10......
  • vue中class和style动态绑定
    使用v-bind指令可以给元素动态绑定class与style属性。1、动态绑定class的三种方式①直接绑定②绑定对象语法:{key(类名):value(布尔值)}③绑定数组③三元运算符来......