[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 ...
随机推荐
- 一文搞懂 Prometheus 的直方图
原文链接:一文搞懂 Prometheus 的直方图 Prometheus 中提供了四种指标类型(参考:Prometheus 的指标类型),其中直方图(Histogram)和摘要(Summary)是最复 ...
- 从原理层面掌握@RequestAttribute、@SessionAttribute的使用【一起学Spring MVC】
每篇一句 改我们就改得:取其精华,去其糟粕.否则木有意义 前言 如果说知道@SessionAttributes这个注解的人已经很少了,那么不需要统计我就可以确定的说:知道@RequestAttribu ...
- Activiti 开发案例之动态指派任务
流程图 以上是一个请假的流程图,以下为流程任务节点描述: 员工发起请假流程 部门经理审批 同意则进入人事审批 拒绝则调整申请或者直接结束流程 人事审批通过则进入销假环节 人事审批拒绝则调整申请或者直接 ...
- Hystrix超时测试
package com.cookie.test; import com.netflix.hystrix.HystrixCommand; import com.netflix.hystrix.Hystr ...
- 使用windows powershell ISE管理命令窗口,并集成git命令
写于2018-09-03(基于win10) 开启 win + s 输入 ise 操作 主要使用新建的power shell选项卡 将git集成到power shell中 安装准备 确定你的power ...
- Sentry错误日志监控你会用了吗?
无论作为新手还是老手程序员在程序的开发过程中,代码运行时难免会抛出异常,而且项目在部署到测试.生产环境后,我们便不可能像在开发时那样容易的及时发现处理错误了.一般我们都是在错误发生一段时间后,错误信息 ...
- git submodule 子模块
### 背景:为什么要用子模块? 在开发项目中可能会遇到这种问题:在你的项目中使用另一个项目,也许这是一个第三方开发的库,或者是你独立开发的并在多个父项目中使用的.简单来说就是A同学开发了一个模块,被 ...
- 详解慢查询日志的相关设置及mysqldumpslow工具
概述 mysql慢查询日志是mysql提供的一种日志记录,它是用来记录在mysql中相应时间超过阈值的语句,就是指运行时间超过long_query_time值的sql,会被记录在慢查询日志中.long ...
- Spring 核心技术(6)
接上篇:Spring 核心技术(5) version 5.1.8.RELEASE 1.5 Bean 作用域 创建 bean 定义时,你创建了一种用于创建 bean 定义中定义的类实例的方法.bean定 ...
- 由group by引发的sql_mode的学习
前言 在一次使用group by查询数据库时,遇到了问题.下面先搭建环境,然后让问题复现,最后分析问题. 一 问题复现 mysql版本 建表插入数据 表的结构 现在问题来了:我想查询上面表中每个部门年 ...