动态规划算法典型应用之背包问题

  • 问题描述:一个旅行者有一个背包,背包的大小为b,可以放入背包的物品有n种,物品j的重量和价值分别为wjw_jwj​和vjv_jvj​ 请问怎么选择放入背包的物品以使得背包的价值最大?

  • 有了之前投资问题的基础,我们很容易发现,背包问题也可以用动态规划算法来解决。动态规划算法的前期准备步骤主要是如何确定子问题的规模,用什么参数来确定,以及用几个参数。和投资问题的两个参数(投资前k个,投x万元)相类似,背包问题也要用两个参数,分别是选择前k个物品,背包的空间为y 这两个参数决定。我们用优化函数Fk(y)F_k(y)Fk​(y)来表示只允许装前k种物品,背包总数不超过y时背包的最大价值。我们计算这个规模的问题时,分两种情况考虑,如果不选择第k个物品,只选择前k-1种物品,而背包仍然是y,也就是Fk−1(y)F_{k-1}(y)Fk−1​(y) ;还有一种情况就是选择了第k个物品,那么剩下的背包空间就是y-w[k],而因为每个物品可以选择多个,所以剩下的背包空间仍然可以在前k个物品中进行选择,那么取得的最大值就是Fk(y−v[k])F_k(y-v[k])Fk​(y−v[k])

  • 所以最后的递推方程就是 Fk(y)=max{Fk−1(y),Fk(y−vk)+wk}F_k(y) = max\{F_{k-1}(y),F_k(y-v_k)+w_k\}Fk​(y)=max{Fk−1​(y),Fk​(y−vk​)+wk​}

  • 我们可以看到背包问题的递推方程在max里面的两个值都运用到了之前规模比较小的子问题,第一个Fk−1(y)F_{k-1}(y)Fk−1​(y) 运用到了 物品种类(k - 1)这个规模参数,而第二个Fk(y−vk)+wkF_k(y-v_k)+w_kFk​(y−vk​)+wk​则在相同物品种类规模k下,运用了背包大小(y−vky-v_ky−vk​)这个规模参数,可以说将规模小的子问题运用得淋漓尽致。而投资问题的递推方程Fk(x)=max0⩽xk⩽x{fk(xk)+Fk−1(x−xk)}F_k(x) = \underset {0\leqslant x_k \leqslant x} {max} \{f_k(x_k) + F_{k-1}(x-x_k)\}Fk​(x)=0⩽xk​⩽xmax​{fk​(xk​)+Fk−1​(x−xk​)} 中因为max中第一个值fk(xk)f_k(x_k)fk​(xk​)收益函数是已知条件,虽然第二个值Fk−1(x−xk)F_{k-1}(x-x_k)Fk−1​(x−xk​)同时运用了项目种类(k-1)这个规模参数和投资钱数x−xkx-x_kx−xk​这个规模参数,但是昨天我在写投资问题博客的时候,感知没有那么强,只注意到了Fk−1F_{k-1}Fk−1​这个项目种类的规模参数,让人忽略了投资钱数这个规模参数。

  • 以下是我根据书上的数据,写的程序

    //背包问题 旅行者有一个背包,可以放入背包的物品有n种,物品j的重量和价值分别是w[j]和v[j].如果背包的最大重量限制是b,怎么样选择放入背包的物品使得背包的价值最大?
    //输入 每个物品的体积和价值 和背包限制b
    //输出 最大价值和具体每个物品如何选取
    #include <iostream>
    #include <algorithm>
    using namespace std;int main()
    {int w[5] = {0, 2, 3, 4, 7};   //每个物品的重量w[0]弃用int v[5] = {0, 1, 3, 5, 9};   //每个物品的价值v[0]弃用int b = 10;                   //背包限制int F[5][11] = {0};           //F[k][y]表示在选择前k个物品,并且背包限重y时,取得的最大收益int tag[5][11] = {0};         //表示计算优化函数F[k][y]所用到的物品的最大标号for (int i = 1; i <= 10; i++) //当只取第一种物品的时候,用当前钱购买尽可能多的数量,便能取得最大收益{F[1][i] = i / w[1] * v[1];if (i / w[1] > 0)tag[1][i] = 1; //表示所选择物品的最大标号elsetag[1][i] = 0;}for (int i = 2; i <= 4; i++) //枚举选择前2个物品..前3个..前4个{for (int j = 1; j <= 10; j++) //枚举背包大小 从1到10{int tmp;if (j - w[i] < 0) //在递推过程种j-w[i]可能会产生负值,这意味着背包刺客能够承受的重量已经小于第k种物品的重量,实际上时不能装的,通过令F[i][j - w[i]]为一个很小的值,从而使 这个值在另一个优化函数比较时被淘汰,从而使得这种装法被排除tmp = -114514;elsetmp = F[i][j - w[i]];if (F[i - 1][j] > (tmp + v[i])) //比较选择第i个物品或者不选择第i个物品哪个价值更大{F[i][j] = F[i - 1][j];tag[i][j] = tag[i - 1][j]; //标明取得最大收益时的物品没有用到i,所以和tag[i - 1][j]的标号相同}else{F[i][j] = (F[i][j - w[i]] + v[i]);tag[i][j] = i; //最大物品编号为i}}}cout << "最大收益:" << F[4][10] << endl;int x[5] = {0}; //用来统计每个物品被选择的数量,初始都为零int space = 10; //一共有十个空间while (1){int i = tag[4][space];x[i]++;space -= w[i];if (space == 0 || i == 0)break;}for (int i = 1; i <= 4; i++)cout << "第" << i << "个物品的数量:" << x[i] << endl;return 0;
    }
    
  • 运行结果

  • 我希望编程不是为了完成老师布置的题目,而是自己发自真地想要学习并掌握某个算法。

动态规划算法典型应用之背包问题相关推荐

  1. 详解动态规划算法(Python实现动态规划算法典型例题)

    动态规划(Dynamic programming) 是一种在数学.计算机科学和经济学中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法. 动态规划算法是通过拆分问题,定义问题状态和状 ...

  2. Java使用动态规划算法思想解决01背包问题

    Java使用动态规划算法思想解决背包问题 背包问题是一种组合优化的NP完全问题.问题可以描述为:给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高 动 ...

  3. 算法:动态规划算法的最佳实践-背包问题

    1.背包问题 有一个背包,容量为4磅,现有如下物品 要求达到的目标为装入的背包的总价值最大 并且重量不超出要求装入的物品不能重复 2.思路分析 背包问题主要是指一个给定容量的背包.若干具有一定价值和重 ...

  4. 动态规划算法问题分析_背包问题_求相隔数据之间最大和_算法理解

    动态规划如何选取一维数组还是二维数组 总结: * 当题目种涉及到两个变量时需要借助二维数组来实现动态规划,例如 背包问题中,涉及容量和重量两个变量,则需要两个维度来考虑 * 当题目中只有一个变量时,使 ...

  5. 野生前端的数据结构练习(11)动态规划算法

    [摘要] dynamic programming被认为是一种与递归相反的技术,递归是从顶部开始分解,通过解决掉所有分解出的问题来解决整个问题,而动态规划是从问题底部开始,解决了小问题后合并为整体的解决 ...

  6. 算法设计与分析第4章 动态规划(一)【背包问题】

    第3章动态规划(一)[背包问题] 基本思想: 动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,但是经分解得到的子问题往往不是互相独立的.不同子问题的数目常常只有多项式量级.在用 ...

  7. 动态规划算法-03背包问题

    背包问题 简介 背包问题一个很著名的动态规划问题,也称为0-1背包问题,很多题都是以此为模板进行魔改的. 问题描述 有N个重量为w1,w2,w3,,,wn且价值为v1,v2,v3,,,vn的物品和一个 ...

  8. 详解:动态规划算法【Java实现】——背包问题

    动态规划 动态规划算法介绍 动态规划算法最佳实践-背包问题 思路分析: 图解分析: ​Java代码实现: 动态规划算法介绍 1)动态规划(Dynamic Programming)算法的核心思想是:将大 ...

  9. 完全背包问题贪心算法c语言,数据结构与算法学习之路:背包问题的贪心算法和动态规划算法...

    一.背包问题描述: 有N种物品和一个重量为M的背包,第i种物品的重量是w[i],价值是p[i].求解将哪些物品装入背包可使这些物品的费用总和不超过背包重量,且价值总和最大. 二.解决方法: 1.贪心算 ...

  10. 总结——01背包问题 (动态规划算法)

    0-1 背包问题:给定 n 种物品和一个容量为 C 的背包,物品 i 的重量是 wi,其价值为 vi . 问:应该如何选择装入背包的物品,使得装入背包中的物品的总价值最大? 分析一波,面对每个物品,我 ...

最新文章

  1. 树莓派电压过低 串口数据错误增多
  2. 使用Filezilla Server配置FTP服务器
  3. GRUB基本使用介绍
  4. 输入法智能化发展历程
  5. Serverless简介
  6. 优酷视频如何意见反馈?优酷视频怎么意见反馈
  7. 【电脑帮助】解决Wind10系统照片中自带的保存的图片和本机照片的问题
  8. mysql 常用函数总计
  9. JAVA的引用类型变量(C/C++中叫指针)
  10. python 腾讯视频签到_腾讯视频自动签到脚本.
  11. c语言判断一个数是否为素数思路,C语言判断一个数是否为素数方法解析
  12. php502 html正常访问,php-fpm 正常启动,nginx也正常启动,但是为什么访问PHP是502
  13. oracle同义词ddl,同义词 oracle,oracle里synonym的作用是什么?
  14. 无人车成功挑战上海路况,连续5小时不接管,谷歌自动驾驶之父看了都打Call...
  15. 修改windows 7的双系统启动菜单
  16. linux 任意音频采样率转换
  17. 比尔·盖茨、UNIX之父等全球14位IT大佬,总结的18句编程名言!
  18. Percona-toolkit工具详解
  19. ORCAD学习系列之二——元器件与线的放置
  20. XV6源码解读:安装与编译

热门文章

  1. 江苏凤凰职教计算机教案,2017年江苏省职业学校教学大赛方案
  2. 计算机家庭组改工作组,win7系统如何更改工作组
  3. ProcessingJS介绍
  4. 复旦计算机对口,2019年长宁区公办初中划片电脑派位对口入学方式
  5. 硬脆材料划片机的工艺参数研究
  6. 反垃圾邮件系统管理手册
  7. 复合文档格式(一)- Excel XLS文件格式
  8. LiveData更新数据报错java.lang.IllegalStateException: Cannot invoke setValue on a background thread
  9. 八个研发物联网产品的重要问题
  10. C++产生随机数字最全教程