暴力递归转动态规划(三)

news2024/11/19 4:32:18

前两篇暴力递归转动态规划的文章中,都是通过从上到下的一种思路来解决的问题,这篇文章会通过数组从左向右遍历的方式,来将暴力递归转成动态规划。

题目
有两个等长的数组 w[] 和 v[],w[i] 和 v[i] 分别表示 i 号物品的重量和价值,给定一个正整数 bag,表示背包的承重,所装货物不能超过背包的承重,返回你能装下最多的价值是多少?

暴力递归
暴力递归的重点就在于尝试,所尝即所得,首先将暴力递归的方法试出来后,根据暴力递归的方法转成动态规划。
方法的整体思想是这样的,不去管之前货物的拿取情况,从第 index 号货物开始,只关注index 和之后的货物,如果要当前货物, 这用背包重量 - 当前货物重量,并获取当前货物价值,如果不要当前货物,则直接 index 向下走。

代码
主方法调用process,根据前面分析,如果process方法能够根据所传参数返回最大价值,则暴力递归方法就完成了,

public static int maxValue(int[] w, int[] v, int bag) {
		//边界判断,如果v w满足以下条件,说明是无用参数,返回0
        if (w == null || v == null || w.length != v.length || w.length == 0 || v.length == 0) {
            return 0;
        }
		
        return process(w, v, bag, 0);
    }

接下来完善process方法。
其中,关于bag的边界条件判断中,有一些小坑,比如说注释中部分:

  1. bag 为什么只能小于 0 ? 因为,如果bag在获取当前货物后,重量刚好为0,下一个货物的weight = 0,但是value巨大,要不要获取? 应该是可以获取的。所以bag < 0。
  2. bag < 0后,为什么返回 -1 而不是 0 ? 因为,如果我当前货物是最后一个,下一个会走index = v.length,会返回0,但如果此时我超重了,bag < 0 的时候也返回0的话,递归返回给上游的信息是不是还要用当前货物的价值 + 这个0,但此时的货物是不应该装背包的,所以要return -1,并且先调用next看要当前货物的返回值来进行判断。
  //不考虑之前的,从index出发,看是否要当前货物
    private static int process(int[] w, int[] v, int bag, int index) {
	     /* if (bag <= 0){
	            return 0;
	        }
	        
	        if (bag < 0){
	            return 0;
	        }
		int p2 = v[index] + process(w, v, bag - w[index], index + 1);
		*/
        if (bag < 0) {
            return -1;
        }
		//当前位置来到了数组长度位置,说明没货物了,return 0。
        if (index == v.length) {
            return 0;
        }

        //如果不要当前货物,则背包重量无变化,去下一个货物
        int p1 = process(w, v, bag, index + 1);
        //如果要当前货物,则背包重量 - 货物重量,并且 + 当前货物价值。
        int p2 = 0;
        //此处需要先判断,当前货物要完后,背包是否超重,所以先获取next的返回值
        int next = process(w, v, bag - w[index], index + 1);
        if (next != -1) {
            p2 = v[index] + next;
        }
        return Math.max(p1, p2);
    }

此时,暴力递归的方法已经完成,来看如果转成动态规划。之前说过,暴力递归转动态规划很重要的一条就是根据可变参数看子过程有没有重复解。这时候举一个实际的例子列出调用过程就能看出来。
代码中,我们的可变参数是bag的剩余和重量和index,从例子中可以看出,有重复解,OK,那我们开始根据暴力递归的代码改动态规划。
在这里插入图片描述

动态规划
根据上面的分析,已经找到了可变参数(index【行】以及背包剩余容量【列】)。根据可变参数确定dp缓存表大小,并创建dp缓存表。
并且根据暴力递归代码可以分析出:

  1. index是可达到数组长度位置。
  2. 背包剩余容量也是从满的开始,所以数组长度位置也是可到达的。

根据暴力递归base case以及调用关系可以分析出。

  1. 当 index == v.length return 0,所以dp表最后一行的值都是0。
  2. 不管是否取当前货物,每次调用process方法都是取index + 1,所以整个依赖过程是前面行依赖后面行,

获取dp表后怎么填充?根据暴力递归改写代码即可!!!所求的值,就是从0开始的背包最大价值,所以获取dp[0][bag]位置数即可。

     //根据可变参数,确定dp表范围
    //N:可到达N ,所以是0 ~ N +1
    //bag: 可到达bag  -1 ~ bag + 1
    public static int maxValue2(int[] w, int[] v, int bag) {
        if (w == null || v == null || w.length != v.length || w.length == 0 || v.length == 0) {
            return 0;
        }
        int N = v.length;
        //数组初始化都是0,所以不用对dp表最后的行进行循环赋值操作
        int[][] dp = new int[N + 1][bag + 1];
		//因为是后面行依赖前面行,所以从最后行开始向前遍历
        for (int index = N - 1 ; index >= 0; index--) {
        	//填充bag剩余容量rest
            for (int rest = 0; rest <= bag; rest++) {
                int p1 = dp[index +1][rest];
                int p2 = 0;
                int next = rest - w[index] < 0 ? -1 : dp[index + 1][rest - w[index]];
                if (next != -1){
                    p2 = v[index] + next;
                }
                dp[index][rest] = Math.max(p1,p2);
            }
        }
        return dp[0][bag];
    }

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

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

相关文章

全球十大安全好用的黄金交易app软件最新排名(综合评测)

随着金融市场的不断发展&#xff0c;黄金交易app软件日益成为投资者不可或缺的工具。然而&#xff0c;面对众多的黄金交易软件&#xff0c;投资者往往感到困惑和难以抉择。本文将根据最新排名&#xff0c;对全球十大安全好用的黄金交易软件进行综合评测&#xff0c;帮助投资者找…

记一次Zip Slip任意文件写漏洞 以及一些参考文章

记一次Zip Slip任意文件写漏洞以及参考文章们 记一次Zip Slip任意文件写漏洞漏洞复现漏洞原理分析扩展延申 参考文章一&#xff1a;Java之解压流&#xff08;ZipInputStream&#xff09;参考文章二&#xff1a;Zip Slip VulnerabilityExploitable Application FlowAre you Vuln…

13.10 语义分割 全卷积网络

语义分割是对图像的每个像素分类 全卷积网络采用卷积神经网络实现从图像像素到像素类别的转换&#xff0c;全卷积网络将中间层特征的高和宽转换回输入图像的尺寸&#xff08;引入转置卷积实现的&#xff09;。 最终的类别预测与输入图像在像素上一一对应。 全卷积网络模型模型…

day 31 面向对象 成员方法

class 类名称&#xff1a; 类的属类(定义在类中的变量&#xff0c;成员变量) 类的行为(定义在类中的函数&#xff0c;成员方法) # 设计一个类&#xff08;类比生活中&#xff1a;设计一张等级表&#xff09; class Student:name Nonegender Nonenatio…

农产品小程序商城搭建宝典

在当今的电子商务时代&#xff0c;农产品小程序商城已经成为了一种新型的电商模式&#xff0c;为许多农产品的生产和销售带来了新的机遇。但是&#xff0c;如何搭建一个功能完善、用户体验优秀的农产品小程序商城呢&#xff1f;下面&#xff0c;我们就来探讨一下。 首先&#x…

抖音电商店铺运营教程,新手开店常见问题解答,醒醒团队分享

我是王路飞。 做抖音小店不可避免会遇到一些问题&#xff0c;尤其是新手&#xff0c;之前没接触过电商&#xff0c;更别说在抖音做电商开店了。 以至于很多新手在抖音开的店铺&#xff0c;类型不太对&#xff0c;类目不太对&#xff0c;不清楚怎么操作和运营&#xff0c;哪哪…

Redis一主一从Docker方式部署通过keepalived和 sentinel哨兵模式实现高可用

有两台服务器一台是主&#xff0c;master : 172.24.69.180 另外一台是从&#xff0c; slave :172.24.69.181 vip 地址&#xff1a; 172.24.69.185 1、关闭防火墙 两台服务器都关闭防火墙 systemctl disable --now firewalld firewall-cmd --state关闭SELinux setenforce 0 …

audio 标签

<audio>标签是HTML5中用于嵌入音频内容的元素。它提供了一种简单的方式来在网页上播放音频文件。 以下是<audio>标签的基本用法&#xff1a; <audio src"路径/到/音频文件.mp3" controls></audio>在上面的示例中&#xff0c;src属性指定了…

Briefings in Bioinformatics投稿经验分享

期刊名: BRIEFINGS IN BIOINFORMATICS期刊名缩写:BRIEF BIOINFORM期刊ISSN:1467-5463E-ISSN:1477-40542023年影响因子/JCR分区:9.5/Q1latex模板:http://static.primary.prod.gcms.the-infra.com/static/site/journals/document/oup-authoring-template.zip?node=7987de4…

langchain介绍之-Prompt

LangChain 是一个基于语言模型开发应用程序的框架。它使得应用程序具备以下特点&#xff1a;1.数据感知&#xff1a;将语言模型与其他数据源连接起来。2.代理性&#xff1a;允许语言模型与其环境进行交互 LangChain 的主要价值在于&#xff1a;组件&#xff1a;用于处理语言模型…

网络编程 day 5

1、根据select TCP服务器流程图编写服务器 #include <myhead.h>#define ERR_MSG(msg) do{\fprintf(stderr, "__%d__:", __LINE__); \perror(msg);\ }while(0)#define PORT 8888 //端口号&#xff0c;范围1024~49151 #define IP "192.168.…

Mysql死锁卡死

查询 show processlist是显示用户正在运行的线程 show processlist;删除卡死的进程id kill 110651;

2023年最新项目追踪工具排行榜发布!

项目跟踪是确保项目顺利交付的重要环节&#xff0c;项目跟踪可以提高团队协作、管理项目风险、控制项目进度。不过对于项目经理而言&#xff0c;如何高效进行项目追踪工作并不是件轻松的工作。 项目跟踪工具的出现&#xff0c;减缓了项目经理的压力&#xff0c;它帮助团队监控…

适配ADRC自抗扰控制算法的MFP450-ADRC 套件焕新而来

关注 FMT 开源自驾仪的开发者可能知道&#xff0c;早在 2018 年 7 月 FMT开源自驾仪的早期版本就已经实现了 ADRC 算法。 经过几年的发展&#xff0c;FMT 在自抗扰控制算法的适配上做了进一步的优化&#xff0c;为了方便科研工作者和开发者快速上手&#xff0c;我们针对搭载 F…

静态代码检查工具PMD安装、使用

介绍 PMD官网&#xff1a;https://pmd.github.io/ 文档&#xff1a;https://docs.pmd-code.org/latest/ https://docs.pmd-code.org/latest/pmd_languages_java.html Java检查规则&#xff1a;https://docs.pmd-code.org/pmd-doc-7.0.0-rc3/pmd_rules_java.html PMD是一款可扩…

掌握这个工具,轻松管理所有物流信息

在电子商务高度发达的今天&#xff0c;物流快递行业在全球范围内发挥着至关重要的作用。然而&#xff0c;在如此复杂的物流环境中&#xff0c;快递退回件的管理和查询成为了一个难题。为了解决这个问题&#xff0c;我们有一个神奇的工具——快递批量查询高手。 快递批量查询高…

OpenGL-入门-BMP像素图glReadPixels(2)保存显示的界面

用glReadPixels保存显示的界面 #include <GL/glut.h> #include <iostream> #include <fstream> #include <vector>// Save pixel data as BMP image void saveBMP(const std::string& filename, int width, int height, const std::vector<GLu…

OA项目之左侧菜单动态选项卡

目录 1.左侧导航 参考地址&#xff1a;http://layui.org.cn/doc/element/nav.html 2.导入数据表及无限级分类 1) 数据导入&#xff08;此步骤在第一次文章已完成&#xff09; 2) 无限级分类&#xff1a;父亲找儿子的过程&#xff0c;将对应的儿子放在父亲下面&#xff0c;形…

无涯教程-Flutter - 简介

Flutter是一个由谷歌开发的开源移动应用软件开发工具包&#xff0c;用于为Android、iOS、 Windows、Mac、Linux、Google Fuchsia开发应用。 通常&#xff0c;创建移动应用程序是一个非常复杂和具有挑战性的任务。有许多框架可用&#xff0c;它提供了开发移动应用程序的出色函数…