【动态规划】【完全背包】力扣322. 零钱兑换

给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。

计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1 。

你可以认为每种硬币的数量是无限的。

示例 1:
输入:coins = [1, 2, 5], amount = 11
输出:3
解释:11 = 5 + 5 + 1

示例 2:
输入:coins = [2], amount = 3
输出:-1

示例 3:
输入:coins = [1], amount = 0
输出:0
在这里插入图片描述
法一:回溯+记忆化搜索

class Solution {vector<int> count;int dp(vector<int>& coins, int rem) {if(rem == 0) return 0;if(rem < 0) return -1;if(count[rem-1] != 0) return count[rem-1];int Min = INT_MAX;for(int coin : coins){int res = dp(coins, rem - coin);if(res >= 0 && res < Min){Min = res + 1;}}count[rem-1] = Min == INT_MAX ? -1 : Min;return count[rem-1];}
public:int coinChange(vector<int>& coins, int amount) {if(amount == 0){return 0;}count.resize(amount);return dp(coins, amount);}
};

时间复杂度:O(Sn),其中 S 是金额,n 是面额数。我们一共需要计算 S 个状态的答案,且每个状态 F(S) 由于上面的记忆化的措施只计算了一次,而计算一个状态的答案需要枚举 n 个面额值,所以一共需要 O(Sn) 的时间复杂度。
空间复杂度:O(S),我们需要额外开一个长为 S 的数组来存储计算出来的答案 F(S) 。

回溯部分:

int dp(vector<int>& coins, int rem) {if(rem == 0) return 0;if(rem < 0) return -1;if(count[rem-1] != 0) return count[rem-1];int Min = INT_MAX;for(int coin : coins){int res = dp(coins, rem - coin);if(res >= 0 && res < Min){Min = res + 1;}}count[rem-1] = Min == INT_MAX ? -1 : Min;return count[rem-1];}

我们定义一个大小在主函数coinChange中定义为amount的数组count来记忆化,减少重复运算额。首先dp的定义是,coins也就是可选择的coins,rem也就是目标金额,也就是说dp(coins, rem)的含义就是,要凑成rem金额,最少需要多少枚硬币。

假设我们在主函数coinChange传入树的头结点dp(coins, amount),那么会发生什么过程?首先dp要计算最少需要多少枚硬币才能凑到目标金额,这时候他就会枚举如果拿了coin金额的一个硬币,那么只要再凑rem-coin金额即可。那么要计算dp(coins, rem),不就是dp(coins, rem - coin) + 1吗,反过来想就是凑够rem - coin金额需要dp(coins, rem-coin)个硬币,那么再拿一个面值为coin的硬币,就可以凑成rem金额,然后硬币数量+1就是最小金额。但是由于dp(coins,rem-coin)由许多种情况构成,coin可以是不同面额,那么为了凑成价值为rem金额的最小硬币数量,就要求coin要满足dp(coins,rem-coin)必须是所有coin情况的最小的硬币数量,这时候再拿一个价值为coin的硬币,才是dp(coins,rem)的最小硬币组合数。这也就是为什么我们要遍历coins中每一个coin的情况,然后才能找到最小的res是多少,然后让他+1 = Min(注意:Min是局部变量,在每个递归中都存在,互不影响)。

有人会好奇那么不断找到最后,会发生什么,当rem == 0的时候,也就是末节点,实际上的含义也就是凑成金额0需要0种组合,这时候他的父节点就会计算res为0,然后记录Min为res+1 = 1。还有一种情况是rem最后小于0,那么说明这种组合是不合理的,这样子,这样一个路径上的coin金额加起来会大于你的目标amount,所以返回-1来说明这种情况不合理,这时候父节点的res由于小于0,则不会考虑记录到Min中。

最后也就是记忆每一种rem的金额的最小硬币数,下次计算金额为rem的dp,就会直接返回count中储存的结果。

法二:动态规划

class Solution {
public:int coinChange(vector<int>& coins, int amount) {vector<int>dp(amount+1, amount+1);dp[0] = 0;for(int i = 1; i <= amount; i++){for(int j = 0; j < coins.size(); j++){if(coins[j] <= i){dp[i] = min(dp[i], dp[i-coins[j]]+1);}}}return dp[amount] == amount + 1 ? -1 : dp[amount];}
};

时间复杂度:O(Sn),其中 S 是金额,n 是面额数。我们一共需要计算 O(S) 个状态,S 为题目所给的总金额。对于每个状态,每次需要枚举 n 个面额来转移状态,所以一共需要 O(Sn) 的时间复杂度。
空间复杂度:O(S)。数组 dp 需要开长度为总金额 S 的空间。

首先是初始化一个大小为amount+1的数组,并初始化所有元素为amount + 1,表示一个不可能的高值,用来初始化 dp 数组。因为不可能需要超过 amount 个硬币来凑成 amount,所以用 amount + 1 来初始化表示不可能的解。

然后遍历从 1 到 amount 的每个金额 i,试图找到每个金额 i 需要的最少硬币数。
内层循环:for (int j = 0; j < (int)coins.size(); ++j),遍历每个硬币面额 coins[j],如果 coins[j] <= i,就可以尝试使用这个硬币凑出金额 i。
dp[i - coins[j]] + 1:表示在凑成金额 i - coins[j] 的基础上再加上一个面额为 coins[j] 的硬币,来凑出金额 i。
dp[i] = min(dp[i], dp[i - coins[j]] + 1):更新 dp[i],取当前 dp[i] 和 dp[i - coins[j]] + 1 的较小值,表示凑出金额 i 所需的最少硬币数。

最后如果dp[amount]没有被更新,返回-1,否则返回能组成该金额的最小硬币数。

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

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

相关文章

【ACM出版,录用检索快】2024年第四届工商管理与数据科学国际学术会议 (BADS 2024,10月25-27)

2024年第四届工商管理与数据科学国际学术会议(BADS 2024)将于2024年10月25-27日在中国重庆召开&#xff0c;大会由喀什大学支持。 在当今全球化与数字化迅速发展的时代&#xff0c;工商管理与数据科学作为推动经济增长和技术进步的重要力量&#xff0c;正以前所未有的速度交叉融…

使用肘部法则确定K-Means中的k值

一 肘部法则 在K-means算法中&#xff0c;对于确定K&#xff08;簇的数目&#xff09;&#xff0c;我们经常使用肘部法则。 肘部法则是一种用于确定在k均值聚类算法中使用的质心数&#xff08;k&#xff09;的技术。 在这种方法中&#xff0c;为了确定k值&#xff0c;我们连续…

二十三种模式之原型模式(类比制作陶器更好理解一些)

1. 设计模式的分类 创建型模式(五种)&#xff1a;工厂方法模式、单例模式、抽象工厂模式、原型模式、建造者模式。 结构型模式(七种)&#xff1a;适配器模式、代理模式、装饰器模式、桥接模式、外观模式、享元模式、组合模式。 行为型模式(十一种)&#xff1a;状态模式、模板方…

刚开始学精益六西格玛管理方法?这份指南建议收藏

精益六西格玛管理方法&#xff0c;作为两大管理哲学的完美结合&#xff0c;正逐渐成为众多企业转型升级的利器。对于刚开始接触这一领域的你来说&#xff0c;掌握精益六西格玛管理的精髓并有效应用于实践中&#xff0c;无疑是一项既具挑战性又极具价值的任务。本文&#xff0c;…

应用连接错误,初始化mysql数据库恢复---惜分飞

有人在部署一个新网站的时候,写错了配置信息,直接导致原有数据库被清掉,并创建了新库和写入了数据(其实本质就是drop table恢复) 登录操作系统查看,发现数据库文件在根分区,创建了新库,写入了数据之外,还有几个G的binlog.全部恢复不太可能,最后客户决定需要恢复的2个核心表数…

.NET 一款在线解密Web.config的脚本

01阅读须知 此文所提供的信息只为网络安全人员对自己所负责的网站、服务器等&#xff08;包括但不限于&#xff09;进行检测或维护参考&#xff0c;未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此文所提供的信息而造成的直接或间接后果和损失&#xf…

官网下载easyx压缩包,如何在devc++配置easyx

视频教程 官网下载easyx压缩包&#xff0c;如何在devc配置easyx EasyX Graphics Library for C 安装指南 1. 访问官网 官网 2. 下载 EasyX 在官网上找到下载区域&#xff0c;点击下载按钮以获取 EasyX 安装包。 3. 访问更多下载选项 点击页面上的“more”链接&#xff0…

Django日志

【图书介绍】《Django 5企业级Web应用开发实战&#xff08;视频教学版&#xff09;》_django 5企业级web应用开发实战(视频教学版)-CSDN博客 《Django 5企业级Web应用开发实战&#xff08;视频教学版&#xff09;》(王金柱)【摘要 书评 试读】- 京东图书 (jd.com) Django 5框…

uniapp 微信小程序自定义tabbar层级低于canvas解决方案

示例代码&#xff1a; <template><cover-view class"tab"><cover-view class"navView" tap"switc(/pages/index/index)"><cover-image :src"tabname index?/static/tabbar/overide-sel.png:/static/tabbar/overide…

Vscode python无法转到函数定义

今天上午换了电脑&#xff0c;使用Vscode发现找不到对应的函数定义了。 使用了网上的全部教程。一点用没有。重启电脑&#xff0c;重启Vscode也没有作用。最后通过重装vscode&#xff0c;解决问题。&#xff08;也不知道Vscode什么毛病&#xff09; 重点语句&#xff1a; 去官网…

大语言模型(LLM)与多模态大模型(MLLM)结合行人重识别(Reid)领域最新文献方法调研

Data Augmentation for Text-based Person Retrieval Using Large Language Models 这篇论文主要研究文本基础的人员检索&#xff08;Text-based Person Retrieval, TPR&#xff09;任务中的数据扩充问题&#xff0c;并提出了一种基于大语言模型&#xff08;Large Language Mo…

framebuffer帧缓存

1. framebuffer Framebuffer&#xff08;帧缓冲区&#xff09;是用于存储图像数据的一块内存区域。我们可以将我们想要显示的图像数据写到framebuffer中&#xff0c;驱动程序每隔一段时间会自动的去读取Framebuffer中的图像数据&#xff0c;并根据读取到的图像数据在屏幕上显示…

最全整理:R/Rstudio/R包的更新

R 是开源的数据分析和统计计算语言&#xff0c;功能强大且应用广泛&#xff0c;R 的版本更新频率较高。最近处理数据时突然有一个 R 包无法安装&#xff0c;细探究发现这个 R 包需要新版本 R 的才可以安装。本文主要分享&#xff1a;更新 R、更新 Rstudio 和一键升级 R 包。 更…

web项目如何部署到服务器上呢?——麻烦的方法

只需关注web项目如何部署到服务器上&#xff0c;因为服务器运行时就可以访问web项目了。 一、麻烦的方法 1、首先启动服务器 &#xff08;1&#xff09;找到bin文件夹 &#xff08;2&#xff09;双击运行startup.bat文件 &#xff08;3&#xff09;运行之后的界面如下&#…

上海亚商投顾:沪指探底回升 华为产业链午后爆发

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 沪指昨日探底回升&#xff0c;深成指、创业板指盘中跌逾1%&#xff0c;午后集体拉升翻红。华为产业链午后走强…

Mysql系列-索引简介

索引是排好序的数据结构 1 索引数据结构 hash索引、二叉树、平衡二叉树、B-Tree、BTree 数据结构在线示例&#xff1a;点击跳转 2 索引类型 2.1 聚簇索引 又叫“聚集索引” &#xff0c;索引和数据存储在一起 2.2 非聚簇索引 又叫“非聚集索引” &#xff0c;索引和数据分开…

Linux系统玩ppsspp

安装ppsspp 在ppsspp的官网&#xff0c;有提供Linux版本的下载链接&#xff0c;仔细一看是flathub的链接&#xff0c;也就是说ppsspp官方推荐采用flatpak安装。 确实有一些发行版提供了自己的ppsspp包&#xff0c;比如说openSUSE和Fedora&#xff0c;不过我自己试用以后发现系…

我的创作纪念日——第0x100天

官方提示今天是开始创作的第256天&#xff0c;最初没反应过来第256天算是个什么纪念日&#xff0c;好像并没什么特殊的啊。仔细一想&#xff0c;难道是第0x100天的意思吗&#xff1f;哈哈&#xff0c;专属于程序猿的浪漫。 既然这样&#xff0c;还是写一篇文章&#xff0c;交个…

前端使用 Konva 实现可视化设计器(22)- 绘制图形(矩形、直线、折线)

本章分享一下如何使用 Konva 绘制基础图形&#xff1a;矩形、直线、折线&#xff0c;希望大家继续关注和支持哈&#xff01; 请大家动动小手&#xff0c;给我一个免费的 Star 吧~ 大家如果发现了 Bug&#xff0c;欢迎来提 Issue 哟~ github源码 gitee源码 示例地址 矩形 先上效…

实现C程序绑定TCP端口

实现C程序绑定TCP端口 步骤概述伪代码C代码实现解释在网络编程中,TCP(传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。绑定TCP端口是服务器端应用程序在网络通信中的一个关键步骤,它允许服务器监听来自客户端的连接请求。 本文将介绍如何使用C语言…