动态规划算法

news2025/1/20 10:49:51

1.简介

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

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

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

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

2.应用场景-背包问题

有一个背包,容量为4磅,现有如下物品: 在这里插入图片描述

要求:

①.达到的目标为装入的背包的总价值最大,并且重量不超出背包的容量;

②.装入的物品不能重复;

2.1.思路分析

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

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

3.算法的主要思想,利用动态规划来解决.每次遍历到的第i个物品,根据w[i]和v[i]来确定是否需要将该物品放入背包中.即对于给定的n个物品,设 v[i]、w[i]分别为第i个物品的价值和重量,C为背包的容量.再令v[i][j]表示在前i个物品中能够装入容量为j的背包中的最大价值.则我们有下面的结果:

在这里插入图片描述
①.v[i][0]=v[0][j]=0: 表示填入表第一行和第一列是0,没有物品的时候背包不管背包的容量是多大,其价值都是0;如果背包的容量为0磅,商品放不进去,其价值也是0;

②.当w[i] > j时: ``v[i][j]=v[i-1][j]` : 表示当准备加入新增的商品的容量大于当前背包的容量时,就直接使用上一个单元格的装入策略;

③.当w[i] <= j时: 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]]: 表示装入商品到剩余空间的最大值;

2.2.代码实现

public class KnapsackProblem {
    public static void main(String[] args) {
        int[] w = {1, 4, 3}; //物品的重量
        int[] val = {1500, 3000, 2000}; //物品的价值
        int m = 4; //背包的容量
        int n = val.length; //物品的个数

        //创建二维数组,表示在前i个物品中能装入容量为j的背包中的最大价值
        int[][] v = new int[n + 1][m + 1];

        //为了记录商品的存放情况,定义二维数组
        int[][] path = new int[n + 1][m + 1];

        //初始化第一行和第一列
        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++) { //跳过第一行,行表示商品信息
            for (int j = 1; j < v[0].length; j++) { //跳过第一列,列表示背包容量
                //注意:由于程序中i是从1开始,表示第二个商品,所以这里要处理下,将w[i]改成w[i-1]
                if (w[i - 1] > j) {
                    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]]);
                    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];
                    }
                }
            }
        }

        for (int i = 0; i < v.length; i++) {
            for (int j = 0; j < v[0].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--;
        }
    }
}

结果:
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

项目统一规范包管理器

一般来说每个团队都会统一规定项目内只使用一个包管理器&#xff0c;譬如&#xff1a;npm、yarn、pnpm等&#xff0c;我们可以在文档中或者项目根目录REDEM.md中进行描述来形成共识&#xff0c;但毕竟是文档&#xff0c;并不能真正的进行约束&#xff0c;如果有项目成员没有看文…

SpringBoot自动装配原理分析,看完你也能手写一个starter组件

什么是 SpringBoot 2012 年 10 月&#xff0c;一个叫 Mike Youngstrom 的人在 Spring Jira 中创建了一个功能请求&#xff0c;要求在 Spring Framework 中支持无容器 Web 应用程序体系结构&#xff0c;提出了在主容器引导 Spring 容器内配置 Web 容器服务。这件事情对 SpringBo…

Linux 进程间通信

目录 进程间通信的必要性 进程间通信的技术背景 进程间通信的本质理解&#xff1a; 管道IPC&#xff1a;匿名管道 示意图 匿名管道的本质原理&#xff1a; demo示例代码&#xff1a; pipe 系统调用 注意&#xff1a; 管道读写的4种情况&#xff1a; 管道的特点&…

H5UI库和二维码

一、H5UI库 1、使用方法&#xff1a; ​ &#xff08;1&#xff09;页面中引入css文件 ​ h5ui.css &#xff08;h5ui.min.css&#xff09; ​ &#xff08;2&#xff09;页面中引入js文件 ​ jquery.min.js ​ h5ui.min.js 2、组件的用法 ​ &#xff08;1&#xff09…

为您的高速SPI添加强大和可靠的隔离交流

介绍 串行外设接口&#xff08;SPI&#xff09;是工业设备中常用于数字处理器核心和外围设备之间通信的一种协议。然而&#xff0c;为了安全使用&#xff0c;有必要对外围设备和核心进行电隔离。虽然隔离和SPI都是成熟的技术&#xff0c;但将两者接口并不像预期的那么简单。 …

SAP ABAP——数据类型(五)【LIKE系列关键字】

&#x1f4ac;个人网站&#xff1a;【芒果个人日志】​​​​​​ &#x1f4ac;原文地址&#xff1a;SAP ABAP——数据类型&#xff08;五&#xff09;【LIKE系列关键字】 - 芒果个人日志 (wyz-math.cn) &#x1f482;作者简介&#xff1a; THUNDER王&#xff0c;一名热爱财税…

【git】简洁实用教程

虽然之前有git的笔记了&#xff0c;但是操作和命令太多&#xff0c;有点冗余&#xff0c;下面整理出最常见的一些场景和git需求。 零、Git速查表 好习惯&#xff1a;每次提交后和开发代码前&#xff0c;都应该pull下 常见命令&#xff1a; git clone拉取服务器代码&#xff0…

深度解读 | 如何构建以指标为核心的ABI平台?

在上期一文中&#xff0c;我们了解到BI不同发展阶段运行模式及遇到的问题。“报表阶段”是以报表粒度进行管理&#xff0c;数据和报表完全耦合在一起&#xff0c;在不同报表间产生数据和指标的冗余和重复&#xff0c;形成报表爆炸、技术债&#xff0c;导致数据不可信、分析不敏…

Windows 7下安装oracle12c报错:O/S-Error:(OS 1385)

查看报错日志&#xff1a;C:\Program Files\Oracle\Inventory\logs\ installActions2015-04-21_09-29-15AM.log, 提示查看&#xff1a; D:\app\Administrator\cfgtoollogs\netca\trace_OraDB12Home1-150421 11上午1616.log &#xff0c; 打开该log&#xff0c;在尾部发现如下错…

LaTeX页眉页脚自定义【有图有代码】

LaTeX页眉页脚自定义【有图有代码】一、自定义页眉页脚示例【双页文档】\fancyhead \fancyfoot1、代码讲解2、自定义代码3、页眉和页脚的装饰线4、总页数二、自定义页眉页脚示例【单页文档】\rhead \rfoot三、\pagestyle{}介绍四、设置当前页面样式\thispagestyle{}平时在写报告…

中级软件设计师备考上午题总结

中级软件设计师备考上午题总结 前言 10月末11月初备考了中级软件设计师&#xff0c;备考时间总计20天整&#xff0c;由于预留的备考时间并不多&#xff0c;上午题复习策略主要是以看别人整理好的笔记为主&#xff0c;不懂的地方以看zst_2001的视频为辅&#xff0c;最后预留了…

JDBC Java对数据库增删改查(完整案例)

目录 一.综合上述7个步骤&#xff0c;实现向student表中插入一条数据。 1、注册驱动 2 、获取数据库连接对象 3、获取发送SQL语句对象 4、编写SQL语句&#xff0c;SQL语句最好是先在SQLyog里面写一遍并运行一下&#xff0c;保证SQL语句没有语法 错误&#xff0c;这里sid是…

C语言百日刷题第十二天

前言 今天是刷题第12天&#xff0c;放弃不难&#xff0c;但坚持一定很酷~ 临近期末&#xff0c;刷几套模拟题 C语言百日刷题第十二天前言选择题判断题编程题选择题 1.设a1;b2;c3;d4;则表达式a<b?a:c<d? a:d的结果是____。 A、3 B、1 C、4 D、2 正确选项&#xf…

Linux多线程(一):什么是线程?

文章目录一、前言二、什么是线程&#xff1f;三、线程是如何实现的&#xff1f;四、基本概念梳理五、后记一、前言 什么是线程&#xff1f;操作系统书籍上可能会给你这样的解释与定义&#xff1a; 线程是在进程内部运行的执行流线程比进程的执行力度更细&#xff0c;线程的调…

年底无情被裁,我面试大厂的这几个月…

2022年接近尾声&#xff0c;“金九十”今年也变成了“铜九铁十”。 大厂不断缩招&#xff0c;不容忽视的疫情影响&#xff0c;加上不断攀升的毕业生人数&#xff0c;各种需要应对的现实问题让整个求职季难上加难。 在这个异常残酷的求职季&#xff0c;很多人的困惑、面临的问…

VM系列模块基本信息

外形尺寸&#xff1a; VM501/604/608 30.0mmX26.0mmX4.3mm 贴插封装-20 VM511/614/618 60.0mmX36.0mmX4.8mm 直插-22 VM704 30.0mmX26.0mmX6.0mm 直插-20 VM704S 32.0mmX32.0mmX15.0mm 直插-20 数字接口&#xff1a;UARTI2C UART&#xff1a;TTL/R…

03-SpringBoot进阶

知识回顾 知识目标 1、SpringBoot单元测试【掌握】 2、SpringBoot 整合 MybatisPlus【重点】 3、SpringBoot添加分页插件【掌握】 4、SpringBoot定义拦截器【掌握】 5、SpringBoot使用类型转换器【掌握】 6、文件上传【掌握】 7、SpringBoot异常处理【掌握】 8、SpringBoot定…

Navicat 16 和表空间 | 第 一 部分

优点 你知道 Navicat 16 支持表空间吗&#xff1f;表空间是表&#xff08;以及索引、大型对象和长数据&#xff09;的存储结构&#xff0c;它将数据库中的数据组织成与在文件系统上存储数据的位置相关的逻辑存储组。它的主要功能是联接物理存储层和逻辑存储层。通过将表分配给表…

c盘空间怎么扩大?

电脑系统主要存储在C盘&#xff0c;用户还可能会将一些软件、文件夹存储在C盘&#xff0c;所以电脑C盘必须拥有足够充足的空间&#xff0c;为了大家更好地使用电脑&#xff0c;这里小编带来的就是电脑扩大C盘空间的教程。 1、右击桌面的计算机图标&#xff0c;然后选择管理! 2、…

过滤器的使用

过滤器的使用过滤器介绍过滤器的使用配置过滤器过滤器路径的配置规则前置、后置、环绕过滤器过滤器链过滤器的优先级过滤器介绍 过滤器(Filter)是位于客户端与服务器资源之间的一道过滤技术&#xff0c;可以在客户端请求到达目标资源之前进行预处理业务。 过滤器作用 执行多个…