java 动态规划 背包问题[通俗易懂]

java 动态规划 背包问题[通俗易懂]背包问题具体例子:假设现有容量10kg的背包,另外有3个物品,分别为a1,a2,a3。物品a1重量为3kg,价值为4;物品a2重量为4kg,价值为5;物品a3重量为5kg,价值为6。将哪些物品放入背包可使得背包中的总价值最大?首先想到的,一般是穷举法,一个一个地试,对于数目小的例子适用,如果容量增大,物品增多,这种方法就无用武之地了。  其次,可以先把价值最大的物体放入,这已经是贪

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

背包问题具体例子:假设现有容量10kg的背包,另外有3个物品,分别为a1,a2,a3。物品a1重量为3kg,价值为4;物品a2重量为4kg,价值为5;物品a3重量为5kg,价值为6。将哪些物品放入背包可使得背包中的总价值最大?

首先想到的,一般是穷举法,一个一个地试,对于数目小的例子适用,如果容量增大,物品增多,这种方法就无用武之地了。

  其次,可以先把价值最大的物体放入,这已经是贪婪算法的雏形了。如果不添加某些特定条件,结果未必可行。

  最后,就是动态规划的思路了。先将原始问题一般化,欲求背包能够获得的总价值,即欲求前i个物体放入容量为m(kg)背包的最大价值c[i][m]——使用一个数组来存储最大价值,当m取10,i取3时,即原始问题了。而前i个物体放入容量为m(kg)的背包,又可以转化成前(i-1)个物体放入背包的问题。下面使用数学表达式描述它们两者之间的具体关系。

  表达式中各个符号的具体含义。

  w[i] :  第i个物体的重量;

  p[i] : 第i个物体的价值;

  c[i][m] : 前i个物体放入容量为m的背包的最大价值;

  c[i-1][m] : 前i-1个物体放入容量为m的背包的最大价值;

  c[i-1][m-w[i]] : 前i-1个物体放入容量为m-w[i]的背包的最大价值;

  由此可得:

      c[i][m]=max{c[i-1][m-w[i]]+pi , c[i-1][m]}(下图将给出更具体的解释)


                       java 动态规划 背包问题[通俗易懂]

根据上式,对物体个数及背包重量进行递推,列出一个表格(见下表),当逐步推出表中每个值的大小,那个最大价值就求出来了。推导过程中,注意一点,最好逐行而非逐列开始推导,先从编号为1的那一行,推出所有c[1][m]的值,再推编号为2的那行c[2][m]的大小。这样便于理解。

                   java 动态规划 背包问题[通俗易懂]

public class BackPack { public static void main(String[] args) { int m = 10; int n = 3; int w[] = {3, 4, 5}; int p[] = {4, 5, 6}; int c[][] = BackPack_Solution(m, n, w, p); for (int i = 1; i <=n; i++) { for (int j = 1; j <=m; j++) { System.out.print(c[i][j]+"\t"); if(j==m){ System.out.println(); } } } //printPack(c, w, m, n); } /** * @param m 表示背包的最大容量 * @param n 表示商品个数 * @param w 表示商品重量数组 * @param p 表示商品价值数组 */ public static int[][] BackPack_Solution(int m, int n, int[] w, int[] p) { //c[i][v]表示前i件物品恰放入一个重量为m的背包可以获得的最大价值 int c[][] = new int[n + 1][m + 1]; for (int i = 0; i < n + 1; i++) c[i][0] = 0; for (int j = 0; j < m + 1; j++) c[0][j] = 0; for (int i = 1; i < n + 1; i++) { for (int j = 1; j < m + 1; j++) { //当物品为i件重量为j时,如果第i件的重量(w[i-1])小于重量j时,c[i][j]为下列两种情况之一: //(1)物品i不放入背包中,所以c[i][j]为c[i-1][j]的值 //(2)物品i放入背包中,则背包剩余重量为j-w[i-1],所以c[i][j]为c[i-1][j-w[i-1]]的值加上当前物品i的价值 if (w[i - 1] <= j) { if (c[i - 1][j] < (c[i - 1][j - w[i - 1]] + p[i - 1])) c[i][j] = c[i - 1][j - w[i - 1]] + p[i - 1]; else c[i][j] = c[i - 1][j]; } else c[i][j] = c[i - 1][j]; } } return c; }
0 0 4 4 4 4 4 4 4 4 0 0 4 5 5 5 9 9 9 9 0 0 4 5 6 6 9 10 11 11 


版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/164400.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 19种电压转换的电路设计方式

    19种电压转换的电路设计方式标准三端线性稳压器的压差通常是2.0-3.0V。要把5V可靠地转换为3.3V,就不能使用它们。压差为几百个毫伏的低压降(LowDropout,LDO)稳压器,是此类应用的理想选择。图1-1是基本LDO系统的框图,标注了相应的电流。从图中可以看出,LDO由四个主要部分组成:技巧一:使用LDO稳压器,5V向3.3V系统供电标准三端线性稳压器的压差通常是2.0-3.0V。要把5V可靠地转换为3.3V,就不能使用它们。压差为几百个毫伏的低压降(LowD…

  • VLAN作用概述_发挥三个作用是指哪三个作用

    VLAN作用概述_发挥三个作用是指哪三个作用VLAN作用

  • Oracle锁表查询和解锁方法

    Oracle锁表查询和解锁方法我们这里一般用的PL/SQL,总是无意间把表锁住,所以我今天就整理了一下简单的解锁和查询锁表的方法;一、首先PL/SQL要以管理员的账号(system/admin等)登录,管理员的账号和密码根据个人设置而来,连接为一般选择Normal,也可选择SYSDBA;二、相关SQL语句:–以下几个为相关表SELECT*FROMv$lock;SELECT*FROMv$sqlarea;S…

  • Python – 编写可视化界面(Python+PyCharm+PyQt)

    Python – 编写可视化界面(Python+PyCharm+PyQt)Python编写可视化界面最近开始学习Python,但只限于看理论,编几行代码,觉得没有意思,就想能不能用Python编写可视化的界面。遂查找了相关资料,发现了PyQt,由于前一段时间刚看过Qt,而且对Qt的印象很好,于是觉得用PyQt应该是一个比较愉快的选择。1、前言PyQt的版本需要与Python的版本保持一致,在这里我用的PyQT的版本是PyQt5-5.6-gp…

  • Tree命令的下载与使用「建议收藏」

    Tree命令的下载与使用「建议收藏」**Tree命令的下载与使用**前言作为一名Linux小白,今天第一次发博客,决定把我今天下载Linux中tree命令的过程记录下来,先来讲一讲我是怎么碰见tree这个命令的吧,今日看书时,无意中翻到tree这个命令得知这个命令可以以树状图列出目录结构,于是我便创建了一个名为aaa的文件夹和一个叫123的文件,并且复制了123文件(123复件),将123文件和123复件移进aaa文件夹,在…

  • matlab中@的用法[通俗易懂]

    matlab中@的用法[通俗易懂]@是用于定义函数句柄的操作符。函数句柄既是一种变量,可以用于传参和赋值;也是可以当做函数名一样使用。举例:sin是matlab中的一个函数,但sin只是函数名,还不是函数句柄,不可以用于传参。f=@sin;这行代码定义了一个函数句柄,变量名是f。这样就可以当做参数传递了(这就是上面代码中的意义所在),而且还可以跟sin函数按相同的语法规则使用:g=f;%g也是函数句柄,其“值”和f一样…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号