16.1 动态规划引入例子:最少硬币问题
文章目录
- 最少硬币问题描述
- 解题思路
- (1) 只使用最小面值的 1 分硬币
- (2)在使用面值1分硬币的基础上,增加使用第二大面值的5分硬币
- (3)继续处理其它面值的硬币
- 参考代码
- 打印最少硬币的组合
最少硬币问题描述
有n种硬币,面值分别为V1,V2,…,Vn.数量无限。输入非负整数S,请你选用硬币,使其和为S。要求输出最少的硬币组合。
解题思路
先定义一个数组int cnt[M],其中 cnt[i] 是金额 i 对应的最少硬币数量。如果程序能计算出所有的 cnt [i],0< i <M,那么对输入的某个金额 i,只要查 cnt[i] 就得到了答案。
那么我们该如何计算 cnt[i] 呢?cnt[i] 和 cnt[i-1]又是否有关系呢?这里涉及到一个“递推”的思路,从小问题 cnt[i-1] 的解决递推到大问题 cnt[i] 的解决。小问题的解决能推导出大问题的解决。下面我们以5种面值[1,5,10,25,50]的硬币为例,讲解从i-1到 i 的递推过程:
(1) 只使用最小面值的 1 分硬币
(2)在使用面值1分硬币的基础上,增加使用第二大面值的5分硬币
(3)继续处理其它面值的硬币
在DP中,把 cnt[i] 这样的记录子问题最优解的数据称为“状态”;从 cnt[i-1] 或 cnt[i-5] 到 cnt[i] 的递推,称为“状态转移”。用前面子问题的结果,推导后续子问题的解,逻辑清晰、计算高效,这就是DP的特点。
参考代码
#include<bits/stdc++.h>
using namespace std;
const int M = 251; //定义最大金额
const int N = 5; //5种硬币
int type[N] = {1, 5, 10, 25, 50}; //5种面值
int cnt[M]; //每个金额对应最少的硬币数量
const int INF = 0x1FFFFFFF;void solve(){for(int k = 0; k< M; k++) //初始值为无穷大cnt[k] = INF;cnt[0] = 0;for(int j = 0; j < N; j++)for(int i = type[j]; i < M; i++)cnt[i] = min(cnt[i], cnt[i - type[j]] + 1); //递推式
}
int main(){int s;solve(); //计算出所有金额对应的最少硬币数量。打表while(cin >> s){if(cnt[s] == INF) cout <<"No answer" << endl;else cout << cnt[s] << endl;}return 0;
}
打印最少硬币的组合
#include<bits/stdc++.h>
using namespace std;
const int M = 251; //定义最大金额
const int N = 5; //5种硬币
int type[N] = {1,5,10,25,50}; //5种面值
int cnt[M]; //每个金额对应最少的硬币数量
int path[M]={0}; //记录最小硬币的路径
const int INF = 0x1FFFFFFF;
void solve(){for(int k=0; k< M;k++)cnt[k] = INF;cnt[0]=0;for(int j = 0;j < N;j++)for(int i = type[j]; i < M; i++)if(cnt[i] > cnt[i - type[j]]+1){path[i] = type[j]; //在每个金额上记录路径,即某个硬币的面值cnt[i] = cnt[i - type[j]] + 1; //递推式}
}
void print_ans(int *path, int s) { //打印硬币组合while(path[s]!=0 && s>0){cout << path[s] << " ";s = s - path[s];}
}
int main() {int s;solve();while(cin >> s){if(cnt[s] == INF)cout <<"No answer"<<endl;else{cout << cnt[s] << endl; //输出最少硬币个数print_ans(path,s); //打印硬币组合}}return 0;
}
16.1 动态规划引入例子:最少硬币问题相关推荐
- 用动态规划算法求解最少硬币问题 c语言,动态规划算法求解硬币找零问题
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 看着这代码怎么这么熟悉. package 动态规划找零; import java.util.Scanner; public class Main { pu ...
- java动态规划凑硬币问题,详解动态规划最少硬币找零问题--JavaScript实现
硬币找零问题是动态规划的一个经典问题,其中最少硬币找零是一个变种,本篇将参照上一篇01背包问题的解题思路,来详细讲解一下最少硬币找零问题.如果你需要查看上一篇,可以点击下面链接: 详解动态规划01背包 ...
- python 最小硬币数_Python之动态规划(最少硬币数找零)
完整代码: # 动态规划最少硬币数找零 def dpMakeChange(coinValueList, change, minCoins, coinsUsed): for cents in range ...
- 最值动态规划——最少硬币组合
#include<iostream> #include<cstdio> #include<cstring> //本来想用 memset 函数来着,后来除了岔子!除了 ...
- 动态规划(三)——最少硬币和所有硬币问题
硬币问题 一.最少硬币问题 二.打印最少硬币组合 三.所有硬币组合 3.1硬币数量不限制 3.2硬币数量限制 一.最少硬币问题 有n种硬币,面值为v1-vn,数量无限,选用硬币,使其和金额为s,要求求 ...
- 动态规划求解最少硬币是多少?
多少枚硬币组合问题,最少硬币是多少? 1 确定状态 最后一步(最优策略中使用的最后一枚硬币) 化成子问题(最少的硬币拼出更小面值) 2 转移方程 3 初始条件和边界情况 f[0]=0,如果不能拼出Y, ...
- 动态规划经典题目-找零钱的最少硬币数
文章目录 一.题目描述 二.解题思路(朴素版本) 1. 定义状态 2. 定义状态转移方程 3. 初始化 三.代码实现 四.优化 五.执行结果 一.题目描述 美国的硬币按照面值1, 5, 10, 2 ...
- 算法——Coin Changing(最少硬币数)
题目描述 设有n 种不同面值的硬币,各硬币的面值存于数组T[1:n]中.现要用这些面值的硬币来找钱.可以使用的各种面值的硬币个数存于数组Coins[1:n]中. 对于给定的1≤n≤10,硬币面值数组T ...
- 最少硬币找零问题(js实现)
最少硬币找零问题 例如,有以下面额(硬币):1,5,10,5. 如果要找36的零钱,我们可以用1个25的硬币.1个10的硬币和1个1的硬币. 如何将这个解答转化成算法? 今天我们只要采用两种方法来解决 ...
最新文章
- MySQL千万级别大表如何优化?
- BugkuCTF-MISC题多方法解决
- 【ElasticSearch】Es 源码之 NamedWriteableRegistry 源码解读
- OpenShift 4 之运行Istio的BookInfo微服务应用
- XML序列之System.Xml.Serialization
- Django-ModelFrom中修改save后的字段值
- SAP License:大话三国之企业点将
- 分布式文件系统MooseFs部署(二)
- springboot不返回指定的字段(隐藏字段)
- 2012年中国40位40岁以下的商界精英榜单
- Xpose模块抓取函数功能学习笔记
- ThinkPHP内核全行业小程序运营管理系统源码 自由DIY布局 一键生成小程序
- pagefile.sys删除
- MySQL重做日志文件放在磁盘_重做日志文件
- Java基础系列28-常用api之包装类
- ES6 — ES11 新特性一篇通
- 闲置台式机+文件服务器,闲置电脑打造NAS:安装群晖NAS系统
- B站到处投资,股价暴跌两位数
- Red Hat Enterprise Linux7.4版本网盘下载
- 2022届秋招面经--秋招面试(3)
热门文章
- Spark:实时数据微批处理(2.Spark Core:核心)
- 大专计算机基础应用毕业设计,大专计算机毕业论文
- 计算机毕业设计ssm科研项目申报系统40lsu系统+程序+源码+lw+远程部署
- 【快手API】根据ID取商品详情 API 返回值说明
- 【物联网平台】智慧消防监控系统介绍
- run cesm2.1.3 with my own forcing dataset
- 10_前端笔记-ViewUI
- 公交车蕴含的软件开发思想
- 哈希码相同,值一定相同?
- 江湖六大门派(按拼音字母顺序,排名不分先后)