暴力递归转动态规划(十四)

题目
arr是面值数组,其中的值都是正数且没有重复。再给定一个正数aim。
每个值都认为是一种面值,且认为张数是无限的。
返回组成aim的最少货币数

暴力递归
依然是面值张数的问题,暴力递归尝试的过程是从数组arr index = 0位置出发,一直到 index = arr.length。如果能够正好凑齐aim,则return 0,否则 return Integer.Max_Value用来进行区分。
需要注意的是:因为是求最少货币数,所以需要通过数组中下一个面值的张数使用 + 当前面值的张数使用,取最小值

代码
如果index == arr.length时,没有面值可以取了,如果此时rest = 0,说明正好凑齐钱数,return 0,否则return MAX_VALUE代表搞不了。
next != MAX_VALUE,则说明使用下一张面值刚好可以凑整aim钱数,那么就用当前面值的张数 zhang + 下一张面值的张数 next,和ans取最小值。
所以要通过MAX_VALUE来进行区分。

public static int minCoins(int[] arr, int aim) {
        return process(0, arr, aim);
    }

    public static int process(int index, int[] arr, int rest) {
        if (index == arr.length) {
            return rest == 0 ? 0 : Integer.MAX_VALUE;
        } else {
            int ans = Integer.MAX_VALUE;
            for (int zhang = 0; zhang * arr[index] <= rest; zhang++) {
                //要去index + 1位置看下一张面值的钱的使用情况
                int next = process(index + 1, arr, rest - zhang * arr[index]);
                // 如果使用下一张面值 恰好可以将 rest凑齐
                if (next != Integer.MAX_VALUE) {
                    //则,将当前使用面值张数 + 下一张面值使用张数 与 ans取最小值
                    ans = Math.min(ans, next + zhang);
                }
            }
            return ans;
        
    }

动态规划
根据暴力递归的代码改写动态规划,可变参数为 剩余金额 rest 和 数组下标 index,因为 rest 可以到达0位置,index可以到达arr.length。所以可以确定dp[][]的大小是 的 dp[arr.length + 1 ][aim + 1]。
确定好dp表大小后,根据暴力递归中的base case来填充dp表的默认值。
可以看到。暴力递归代码中,当index == arr.length时, 如果此时剩余金额 rest = 0,则return 0 ,否则 return MAX_VALUE。又因为int型数组,创建后,每个格子默认值就是0,所以只需要将dp[arr.length][1 ~ aim]的位置填充即可。其余代码照抄,dp表就填充完成了。

代码
暴力递归代码中,每次都是依赖index + 1位置 rest - zhang * arr[index],所以外层循环从N -1向0处遍历, 内循环 rest从0 向aim处遍历。

  public static int dp(int[] arr, int aim) {
        int N = arr.length;
        int[][] dp = new int[N + 1][aim + 1];

        for (int rest = 1; rest <= aim;rest ++){
            dp[N][rest] = Integer.MAX_VALUE;
        }
        for (int index = N - 1; index >= 0; index--) {
            for (int rest = 0; rest <= aim; rest++) {
                int ans = Integer.MAX_VALUE;
                for (int zhang = 0; zhang * arr[index] <= rest; zhang++) {
                    int next = dp[index + 1][rest - zhang * arr[index]];
                    if (next != Integer.MAX_VALUE) {
                        ans = Math.min(ans, next + zhang);
                    }
                    dp[index][rest] = ans;
                }
            }
        }
        return dp[0][aim];
    }

再次优化
可以看到动态规划的代码中,每填充1个dp表中格子都有枚举行为(zhang的for循环)。所以还可以再次进行优化。找到dp表中的依赖关系,替换掉这个for循环即可。
找依赖关系最直观的方法就是画图。
假设当前我剩余钱数 = 11,面值为3。
在这里插入图片描述
根据暴力递归代码带入看一下,我依赖的a0 ~ d3,当前面值使用0张,1张。。。的各种情况向下递归。
那如果此时rest = 8,依赖的就是b1 ~ d3,不过此时使用的张数也是0张、1张。。。。以此类推。
所以想要求 √ 位置的值,就是 a0 + (x + 1)。
为什么要加1呢? 还是回到暴力递归中的代码来看 这行代码 ans = Math.min(ans, next + zhang);
如果我next有效,我用的是 next + zhang,是在我当前面值使用了1,2,3若干张之后的情况,所以x位置,也是 √ 使用的一张arr[index]后剩余的rest = 8。

代码
首先保证左侧有值,并且左侧的值是有效的才进行比较。

public static int bestDP(int[] arr, int aim) {
        int N = arr.length;
        int[][] dp = new int[N + 1][aim + 1];

        for (int rest = 1; rest <= aim;rest ++){
            dp[N][rest] = Integer.MAX_VALUE;
        }
        for (int index = N - 1; index >= 0; index--) {
            for (int rest = 0; rest <= aim; rest++) {
                dp[index][rest] = dp[index + 1][rest];
                if (rest - arr[index] >= 0 && dp[index][rest - arr[index]] != Integer.MAX_VALUE) {
                    dp[index][rest] = Math.min(dp[index][rest], dp[index][rest - arr[index]] + 1);
                }
            }
        }
        return dp[0][aim];
    }

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

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

相关文章

sql注入学习笔记

sql注入原理 掌握sql注入漏洞的原理掌握sql注入漏洞的分类 万能用户名 777 or 11 #原句 select userid from cms_users where username ".$username." and password".md5 ( $password ) ."输入过后为 select userid from cms_users where username …

GDPU 数据结构 天码行空9

实验九 哈夫曼编码 一、【实验目的】 1、理解哈夫曼树的基本概念 2、掌握哈夫曼树的构造及数据结构设计 3、掌握哈夫曼编码问题设计和实现 二、【实验内容】 1、假设用于通信的电文仅由8个字母 {a, b, c, d, e, f, g, h} 构成&#xff0c;它们在电文中出现的概率分别为{ 0.…

华为云,阿里云,腾讯云 安全组配置规则

1.安全组常用端口 端口服务说明21FTPFTP服务所开放的端口&#xff0c;用于上传、下载文件。22SSHSSH端口&#xff0c;用于通过命令行模式或远程连接软件&#xff08;例如PuTTY、Xshell、SecureCRT等&#xff09;连接Linux实例。23TelnetTelnet端口&#xff0c;用于Telnet远程登…

【教学类-40-04】A4骰子纸模制作4.0(4.5CM嵌套+记录表带符号)

作品展示 背景需求 骰子3.0&#xff08;7字形&#xff09;存在问题&#xff1a;6.5骰子体积大大&#xff0c;不适合幼儿操作&#xff08;和幼儿手掌一样大&#xff0c;制作耗时&#xff0c;甩动费力&#xff09; 1.0版本&#xff1a;边缘折线多&#xff0c;幼儿剪起来费力。 …

【网络编程】传输层——TCP协议

文章目录 TCP协议TCP协议格式窗口大小六个标志位确认应答机制超时重传机制连接管理机制三次握手四次挥手 流量控制滑动窗口拥塞控制延迟应答捎带应答面向字节流粘包问题TCP异常情况TCP小结基于TCP的应用层协议TCP与UDP的对比 TCP相关实验CLOSE_WAIT状态实验TIME_WAIT状态实验TI…

动态规划(3)---Leetcode509.斐波那契数

题目 分析 很明显的动态规划&#xff0c;直接写出。之前都是用递归来写。 题解 class Solution {public int fib(int n) {if (n0) return 0;if (n1) return 1;int q0,p1,r0;for(int i2;i<n;i){rqp;int tmpp;pr;qtmp; }return r;}

Postgresql数据类型-时间类型

PostgreSQL对时间、日期数据类型的支持丰富而灵活&#xff0c;本节介绍PostgreSQL支持的时间、日期类型&#xff0c;及其操作符和常用函数。 PostgreSQL支持的时间、日期类型如表所示。 我们通过一个简单的例子理解这几个时间、日期数据类型&#xff0c;先来看看系统自带的now…

解决“找不到vcruntime140.dll,无法继续执行代码”错误的方法,以及解决步骤

给大家分享解决“找不到vcruntime140.dll,无法继续执行代码”错误的方法&#xff0c;以及解决步骤&#xff0c;来看看都有哪些可行性的办法解决“找不到vcruntime140.dll,无法继续执行代码”吧。 一.vcruntime140.dll的常见问题 vcruntime140.dll是Microsoft Visual Studio Re…

iis 部署 netcore 和vue 共用端口

常规情况下&#xff0c;vue 和api是分开的两个站点进行部署&#xff0c;若是要对外只有一个端口的话&#xff0c;采用以下梁总方式即可。 1.需要配置路由转发和代理开启&#xff08;vue 使用hisoty模式&#xff09; 参考链接.netCore vue&#xff08;history模式&#xff0…

如何批量下载iconfont图标库

如何批量下载iconfont中svg图 原文链接&#xff1a; https://gitee.com/veigarchen/iconfont-download 1、下载插件到本地 2、将解压的文件添加到浏览器扩展中 3、按需下载自己的图标

华为Auth-Http Serve任意文件读取

1.漏洞描述 华为Auth-Http Server 1.0任意文件读取&#xff0c;攻击者可通过该漏洞读取任意文件。 2.网络资产查找 FOFA&#xff1a;server”Huawei Auth-Http Server 1.0” 2、部分界面如下 3、Poc /umweb/shadow 4、Poc批量验证 id: huanwei-auth-http-server-filereadi…

2023中国互联网公司排行榜!

日前&#xff0c;中国互联网协会正式发布《中国互联网企业综合实力指数&#xff08;2023&#xff09;》报告&#xff0c;同时还发布了2023年中国互联网综合实力前百家企业榜单、2023年中国互联网成长型前二十家企业和数据安全服务前五家企业名单。 总体来看&#xff0c;我国互…

苹果Apple ID忘了或者咨询其他问题如何让苹果客服打电话给你

环境&#xff1a; iPhone11 Apple ID 问题描述&#xff1a; 苹果Apple ID忘了或者咨询其他问题如何让苹果客服打电话给你 上次公司苹果设备&#xff0c;忘了激活锁的账户密码要向苹果申请解锁&#xff0c;打了很长电话&#xff0c;平时语音超套餐了&#xff0c;想着让他们…

Qt 4.8.6 的下载与安装

Qt 4.8.6 的下载与安装 Qt 4.8.6 的下载与安装下载并解压 MinGW 4.8.2Qt4.8.6 库的安装Qt Creator 3.3.0 的安装配置 Qt Creator测试 Qt 4.8.6 的下载与安装 学习《Qt Creator快速入门》&#xff08;第3版&#xff09;&#xff0c;书里面要用 Qt:phonon&#xff0c;这个组件要…

yolov8模型训练、目标跟踪

一、准备条件 1.下载yolov8 https://github.com/ultralytics/ultralytics2.安装python https://www.python.org/ftp/python/3.8.0/python-3.8.0-amd64.exe3.安装依赖 进入ultralytics-main&#xff0c;执行&#xff1a; pip install -r requirements.txt pip install -U ul…

【Git】git的安装与使用教程

【Git】git的安装与使用教程 1.简介1.1.什么是Git1.2.Git与SVN的区别 二、安装Git三、注册Gitee帐号四、使用Git进行上传与下载代码五、使用Git代码冲突六、Git常用命令 1.简介 1.1.什么是Git Git是一个分布式版本控制系统&#xff0c;用于跟踪和管理项目代码的变更。它可以记…

c++day6

#include <iostream>using namespace std; class Animal { public:virtual void peform() 0; }; class Monekey:public Animal { public:void peform(){cout << "猴子黑桃A" << endl;} }; class Elepthant:public Animal {void peform(){cout &l…

软文推广中如何搭建媒体矩阵

媒体矩阵简单理解就是在不同的媒体平台上&#xff0c;根据运营目标和需求&#xff0c;建立起全面系统的媒体布局&#xff0c;进行多平台同步运营。接下来媒介盒子就来和大家聊聊&#xff0c;企业在软文推广过程中为什么需要搭建媒体矩阵&#xff0c;又该如何搭建媒体矩阵。 一、…

LeetCode_多源 BFS_中等_2258.逃离火灾

目录 1.题目2.思路3.代码实现&#xff08;Java&#xff09; 1.题目 给你一个下标从 0 开始大小为 m x n 的二维整数数组 grid &#xff0c;它表示一个网格图。每个格子为下面 3 个值之一&#xff1a; 0 表示草地。1 表示着火的格子。2 表示一座墙&#xff0c;你跟火都不能通过…

能源监测管理系统有哪些作用与效果?

随着全球能源的不断增加&#xff0c;能源的有限性与环境问题日益严重&#xff0c;用能管理企业需要一种高效的方法来管理能源与利用能源&#xff0c;因此能源监测管理系统成为了一种不可或缺的工具。 能源监测管理系统的重要性 1、实现节能减排的目标 通过系统&#xff0c;可…