[DP]换钱的最小货币数
题目一
给定数组arr,数组中有N个元素,其中所有的之都为整数且不重复.每个只代表一种面值的货币,每种面值的货币可以使用任意张,在给定一个整数aim代表要找的钱数,求组成aim的最少货币数.
解法
依然是用二维数组分析的动态规划问题,数组dp长为N行aim-1列.其中dp[i][j]代表用arr[0...i]中出现的面值构成钱数为j所需要的钱的最小张数.那么就有
dp[i][j] = min{dp[i-1][j], dp[i][j - arr[i]] + 1}
整个过程中时间复杂度和空间复杂度分别为O(N*aim)
代码
int minCoins1(int arr[], int length, int aim) {
if (length == 0 || aim == 0)
return 0;
if (aim < 0)
return -1;
int maxInt = INT_MAX;
int dp[length][aim + 1];
for (int j = 1; j < aim + 1; j ++) { //初始化第一行
if (j - arr[0] >=0 && j % arr[0] == 0)
dp[0][j] = j / arr[0];
else
dp[0][j] = maxInt;
}
//从左到右,从上倒下计算dp矩阵
for (int i = 1; i < length; i ++) {
for (int j = 1; j <= aim; j ++) {
if (j - arr[i] >= 0 && dp[i][j - arr[i]] != maxInt)
dp[i][j] = min(dp[i - 1][j], dp[i][j - arr[i]] + 1);
else
dp[i][j] = dp[i - 1][j];
}
}
// for (int i = 0; i < length; i ++) {
// for (int j = 0; j < aim + 1; j ++)
// cout<<dp[i][j]<<" ";
// cout<<endl;
// }
return dp[length - 1][aim] != maxInt ? dp[length - 1][aim]:-1;
}
输入
arr={5,2,3} 20
arr={3,5} -1
输出
4
-1
题目二
给定数组arr,arr中所有的值都为整数.每个值仅代表一张钱的面值,在给定一个整数aim代表要找的钱数, 求组成aim的最少货币数.
解法
同上面一样,我们需要的dp矩阵为N行aim+1列.dp[i][j]代表用arr[0...i]中的钱组成钱数为j所用的最小张数张数.和题目一不同的是根据题意,这里是不允许重复使用面值的.所以dp矩阵初始化第一行是不同的.但是他们有相同的转移方程:
dp[i][j] = min{dp[i-1][j], dp[i][j - arr[i]] + 1}
复杂度也和题目一相似
代码
int minCoins2(int arr[], int length, int aim) {
if (aim < 0)
return -1;
if (length == 0 || aim == 0)
return 0;
int maxInt = INT_MAX;
int dp[length][aim + 1];
for (int i = 0; i < aim + 1; i ++) { //初始化第一行
if (i == arr[0])
dp[0][i] = 1;
else
dp[0][i] = maxInt;
}
for (int i = 1; i < length; i++) {
for (int j = 1; j <= aim; j++) {
if (j - arr[i] >= 0 && dp[i - 1][j - arr[i]] != maxInt)
dp[i][j] = min(dp[i - 1][j - arr[i]] + 1, dp[i - 1][j]);
else
dp[i][j] = dp[i - 1][j];
}
}
return dp[length - 1][aim] != maxInt ? dp[length - 1][aim]:-1;
}
输入
arr={5,2,3}, aim = 20
arr = {5,2,5,3},aim = 15
输出
-1
4
拓展
上面两题都是用的经典动态规划的方式,使用的二维数组.一个常用的优化方式是使用长度为N的一维数组滚动求取,节省了空间开销
[DP]换钱的最小货币数的更多相关文章
- OptimalSolution(1)--递归和动态规划(2)矩阵的最小路径和与换钱的最少货币数问题
一.矩阵的最小路径和 1 3 5 9 1 4 9 18 1 4 9 18 8 1 3 4 9 9 5 8 12 5 0 6 1 14 14 5 11 12 8 8 4 0 22 22 13 15 12 ...
- [程序员代码面试指南]递归和动态规划-换钱的最少货币数(DP,完全背包)
题目描述 给定arr,arr中所有的值都为正数且不重复.每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个整数aim,求组成aim的最少货币数. 解题思路 dp[i][j]表示只用第0 ...
- 算法之Python实现 - 002 : 换钱的最少货币数补充(每种货币只能使用一次)
[题目]:给定数组arr,arr中所有的值都为正数且不重复.每个值代表一种面值的货币,每种面值的货币仅可以使用一张,再给定一个整数aim代表要找的钱数,求组成aim的最少货币数. [代码1]:时间与额 ...
- 算法之Python实现 - 001 : 换钱的最少货币数
[题目]给定数组arr,arr中所有的值都为正数且不重复.每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个整数aim代表要找的钱数,求组成aim的最少货币数. [代码1]:时间与额外 ...
- 剑指OFFER之把数组排成最小的数(九度OJ1504)
题目描述: 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个.例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323. 输入: 输 ...
- 九度OJ 1504 把数组排成最小的数【算法】-- 2009年百度面试题
题目地址:http://ac.jobdu.com/problem.php?pid=1504 题目描述: 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个.例如 ...
- 通过设置线程池的最小线程数来提高task的效率,SetMinThreads。
http://www.cnblogs.com/Charltsing/p/taskpoolthread.html task默认对线程的调度是逐步增加的,连续多次运行并发线程,会提高占用的线程数,而等若干 ...
- 《剑指offer》第四十五题(把数组排成最小的数)
// 面试题45:把数组排成最小的数 // 题目:输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼 // 接出的所有数字中最小的一个.例如输入数组{3, 32, 321},则打印出这3 ...
- 《剑指offer》— JavaScript(32)把数组排成最小的数
把数组排成最小的数 题目描述 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个.例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为3213 ...
随机推荐
- Java线程池的增长过程
通过ThreadPoolExecutor的方式创建线程池 ThreadPoolExecutor 构造方法: public ThreadPoolExecutor(int corePoolSize, in ...
- 小X的逆袭
[问题描述]毕业于普通本科的小x 一直自称是资深屌丝.谁又能想到,如此不起眼的小x 在历经重重面试环节后,竟然如愿以偿加入了心仪已久的腾讯公司!正所谓野百合也有春天,屌丝也有逆袭的那一天!一段时间以后 ...
- hadoop学习(七)----mapReduce原理以及操作过程
前面我们使用HDFS进行了相关的操作,也了解了HDFS的原理和机制,有了分布式文件系统我们如何去处理文件呢,这就的提到hadoop的第二个组成部分-MapReduce. MapReduce充分借鉴了分 ...
- python 之 前端开发(基本选择器、组合选择器、 交集与并集选择器、序列选择器、属性选择器、伪类选择器、伪元素选择器)
11.3 css 11.31 基本选择器 11.311 id选择器 根据指定的id名称,在当前界面中找到对应的唯一一个的标签,然后设置属性 <!DOCTYPE html> <html ...
- 从原理层面掌握@ModelAttribute的使用(使用篇)【一起学Spring MVC】
每篇一句 每个人都应该想清楚这个问题:你是祖师爷赏饭吃的,还是靠老天爷赏饭吃的 前言 上篇文章 描绘了@ModelAttribute的核心原理,这篇聚焦在场景使用上,演示@ModelAttribute ...
- (二十)c#Winform自定义控件-有后退的窗体
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...
- 100天搞定机器学习|day43 几张GIF理解K-均值聚类原理
前文推荐 如何正确使用「K均值聚类」? KMeans算法是典型的基于距离的聚类算法,采用距离作为相似性的评价指标,即认为两个对象的距离越近,其相似度就越大.该算法认为簇是由距离靠近的对象组成的,因此把 ...
- React 多副本问题
Element ref was specified as a string (MySider) but no owner was set. This could happen for one of t ...
- windows安装nginx、mysql等软件并加入系统服务启动详细
windows类系统安装nginx.mysql软件 (PS:windows系统环境中设置完nginx.mysql环境变量,需要重新启动系统才会生效.) 一.NGINX:首先下载windows版ngin ...
- 从零开始实现ASP.NET Core MVC的插件式开发(五) - 插件的删除和升级
标题:从零开始实现ASP.NET Core MVC的插件式开发(五) - 使用AssemblyLoadContext实现插件的升级和删除 作者:Lamond Lu 地址:https://www.cnb ...