动态规划算法(背包问题)

news/2024/4/29 7:42:18/文章来源:https://www.cnblogs.com/y-tao/p/16633760.html

1.应用场景-背包问题

背包问题:有一个背包,容量为4磅 ,现有如下物品

1661686300557

1)要求达到的目标为装入的背包的总价值最大,并且重量不超出

2)要求装入的物品不能重复

2.动态规划算法介绍

1)动态规划(Dynamic Programming)算法的核心思想是:将大问题划分为小问题进行解决,从而一步步获取最优解的处理算法

2)动态规划算法与分治算法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。

3)与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。 ( 即下一个子阶段的求解是建立在上一个子阶段的解的基础上,进行进一步的求解 )

4)动态规划可以通过填表的方式来逐步推进,得到最优解.

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

思路分析和图解

•背包问题主要是指一个给定容量的背包、若干具有一定价值和重量的物品,如何选择物品放入背包使物品的价值最大。其中又分01背包和完全背包(完全背包指的是:每种物品都有无限件可用)

•这里的问题属于01背包,即每个物品最多放一个。而无限背包可以转化为01背包。

算法的主要思想

利用动态规划来解决。每次遍历到的第i个物品,根据w[i]和v[i]来确定是否需要将该物品放入背包中。即对于给定的n个物品,设v[i]、w[i]分别为第i个物品的价值和重量,C为背包的容量。

再令v[i][j]表示在前i(行数)个物品中能够装入容量为j(列数)的背包中的最大价值。则我们有下面的结果:

1661688038959

(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]]} :

验证公式:

v[1][1] =1500

  1. i = 1, j = 1

  2. w[i] = w[1] = 1

w [1] = 1 j = 1 v[i][j]=max{v[i-1][j], v[i]+v[i-1][j-w[i]]} :

v[1][1] = max {v[0][1], v[1] + v[0][1-1]} = max{0, 1500 + 0} = 1500

v[3][4]

  1. i = 3;j = 4

w[i] = w[3] =3 j = 4

j = 4 >= w[i] = 3 => 4 >= 3

v[3][4] = max {v[2][4], v[3] + v[2][1]} = max{3000, 2000+1500} = 2000+1500

4.代码实现

package com.yt.dynamic;public class KnapstackProblem {public static void main(String[] args) {// TODO Auto-generated method stubint[] 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];//初始化第一行和第一列,当然可以不用处理,以为默认值都是0for(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 {//说明:注意下标需要减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];}}}}//输出vfor(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();}System.out.println("===============================");// 输出最后放入的商品是哪些//遍历path,输出所有的放入商品的情况,	其实我们只需要最后一次的输出
//		for(int i =0; i<path.length;i++){
//			for(int j=0; j<path[i].length;j++){
//				if (path[i][j] == 1) {
//					System.out.printf("第%d个商品放入到背包\n" , i);
//				}				
//			}
//		}
//		//动脑筋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];}i--;}}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_2888.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

开启apache服务器gzip压缩

开启apache服务器gzip压缩-百度经验 https://jingyan.baidu.com/article/db55b609a7bc234ba20a2f7e.html 从服务端优化来说,通过对服务端做压缩配置可以大大减小文本文件的体积,从而使加载文本的速度成倍的加快。目前比较通用的压缩方法是启用gzip压缩。它会把浏览器请求的页…

Linux修改主机静态IP

通过VIM编辑器打开主机配置文件夹vim /etc/sysconfig/network-scripts/ifcfg-ens33修改IP地址为静态地址BOOTPROTO="static"添加静态IP地址和网关IP 地址 IPADDR=192.168.244.100 网关 GATEWAY=192.168.244.2 域名解析器 DNS1=192.168.244.2网络重启service network …

点击按钮收藏

分析 后台代码RouteServlet类:/*** 添加收藏* @param request* @param response* @throws ServletException* @throws IOException*/public void addFavorite(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//1、获取线…

前端5JQ

js获取用户输入 JS类属性操作 JS样式操作 事件 JS事件案例 JQuery类库 JQuery基本使用 基本筛选器(了解) 表单筛选器Js获取用户输入 普通数据(输入,选择) ​ 标签对象.value 获取文件数据的时候: 标签对象.value只能获取到文件路径,而标签对象.files结果是一个数组,可以通…

前端Day10

视口(viewport):浏览器显示页面内容的屏幕区域。分为布局视口、视觉视口、理想视口。 布局视口: 视觉视口: 理想视口: meta视口标签: width=device-width:布局视口宽度为当前设备宽度* user-scalable=no:不允许用户缩放 二倍图: 1.物理像素比: ①物理像素:即分辨…

分布式系统的session共享问题

目前大多数大型网站的服务器都采用了分布式服务集群的部署方式。所谓集群,就是让一组计算机服务器协同工作,解决大并发,大数据量瓶颈问题。但是在服务集群中,session共享往往是一个比较头疼的问题。因为session是在服务器端保存的,如果用户跳转到其他服务器的话,session就…

网络network

网络network 基础network模型 OSI七层模型,一层一层封装数据帧(添加报文头),传过去之后再一层一层解封装(解封装掉报文头) 应用层:应用软件层面业务端口,例如http/https,ftp,sftp,smtp(25),除了在四层TCP IP+端口号的方式进行外,还需要检查http/https的url,cook…

python中的多线程与多进程

线程概念: 线程也叫轻量级进程,是操作系统能够进行运算调度的最小单位,它被包涵在进程之中,是进程中的实际运作单位。 线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其他线程共享进程所拥有的全部资源。一个线程可以创建和撤销另一…

从设计到代码(第 3 天)

从设计到代码(第 3 天) 我最近正在开发一门课程,名为 三周内完成三个网页设计 .最初它是一个为期 3 周的研讨会材料,旨在成为一个包含许多实践的动手密集型研讨会。主要目标是教没有太多开发经验的人使用 HTML 和 CSS 来重现专业的设计模型——这就是为什么它被称为从设计到…

力扣507(java)-完美数(简单)

题目: 对于一个 正整数,如果它和除了它自身以外的所有 正因子 之和相等,我们称它为 「完美数」。 给定一个 整数 n, 如果是完美数,返回 true;否则返回 false。示例 1: 输入:num = 28输出:true解释:28 = 1 + 2 + 4 + 7 + 141, 2, 4, 7和 14 是 28 的所有正因子。示例 …

仅Intel电脑可用:设计2D/3D文档绘图Autodesk AutoCAD 2021

Autodesk AutoCAD 2021是Mac上的二维和三维CAD设计软件,用于产品衍生式设计,创建设计方案,三维模型参数化,建模部件组织,创建制作清晰工程图,设计自动化配置等,AutoCAD 2021增强了针对草图的命令设计,简化流程,改进各种性能,转化探索更强大的设计。​编辑切换为居中 …

Echarts与ajax数据的动态交互

初学Echarts,Echarts的官网示例中配置项的数据需要用到js数组来传递数据,所以当我们从后端查询到数据后,往往需要通过ajax来进行数据交互。 这是官方示例的配置项。<script type="text/javascript">// 基于准备好的dom,初始化echarts实例var myChart = ech…

Openwrt 纯ipv6环境管理和上网

防火墙打开远程管理端口 添加端口如22或者使用ipv6端口转发到ipv4 使用socat opkg install socat图形化界面: drophair / luci-app-socatg wget -P /tmp https://github.com/big-tooth/luci-app-socatg/releases/download/v1.1/luci-app-socatg_1.1-1_all.ipk opkg install /tm…

c++ :虚拟机centos7+vscode

c++ :虚拟机centos7+vscodegcc、g++、make查看是否安装成功 $ gcc --version $ g++ --version $ make --version哪个没有,就yum install gcc-c++/yum install gcc/yum install make yum报错 "Failed to connect to 2001:da8:8000:6023::230: 网络不可达":参考链接…

最大正方形

问题:在一个由 0 和 1 组成的二维矩阵内,找到只包含 1 的最大正方形,并返回其面积。 输入:matrix = [["1","0","1","0","0"],["1","0","1","1","1"],["1"…

图解AspNetCore和Furion(1):应用启动

一、和AspNetCore5相比,从6开始,将Program和Startup类合并,直接在入口类中启动服务和中间件。同时,项目可以启动miniApi,直接在Program中设置路由和控制器。实际项目中,还是推荐使用控制器的方式。 二、Furion定义了静态类Serve,对AspNetCore的启动类进行了封装,同时支…

leetcode-172. 阶乘后的零

172. 阶乘后的零 图床:blogimg/刷题记录/leetcode/172/ 刷题代码汇总:https://www.cnblogs.com/geaming/p/16428234.html 题目思路 n!中有几个0与[1,n]中出现多少个5的因数有关。例如7! = 1234567出现了1次5,故最后末尾会出现1个0。26!中出现了5,10,15,20,25其中5的个数为1+…

java内部类

一、基本介绍 一个类的内部又完整的嵌套了另一个类结构。被嵌套的类称为内部类(inner class),嵌套其他类的类称为外部类(outer class)。是我们类的第五大成员 类的五大成员:属性、方法、构造器、代码块、内部类 内部类最大的特点就是可以直接访问私有属性,并且可以体现类…

redis主从数据同步原理

what:redis高可用:1、数据尽量不丢失;2、尽可能的提供服务;栗子:AOF 和 RDB 保证了数据持久化尽量不丢失;主从复制就是增加副本,一份数据保存到多个实例上。即使有一个实例宕机,其他实例依然可以持续服务;主从:复制——为单向的,即:只能从主复制到从;读写指责——…

Linux驱动开发十六.input系统——2.input_event

我们上一章完成了input子系统的设备构成,并且在用户空间通过hexdump命令拿到了一堆不知道是什么的信息。今天我们就要借助input_event这个结构体来了解内核怎么通过那个结构体了解输入事件。 可能有心人已经发现了,上一章我们在加载完模块以后在/dev/input路径下生成了一个新…