题目一

给定数组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]换钱的最小货币数的更多相关文章

  1. 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 ...

  2. [程序员代码面试指南]递归和动态规划-换钱的最少货币数(DP,完全背包)

    题目描述 给定arr,arr中所有的值都为正数且不重复.每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个整数aim,求组成aim的最少货币数. 解题思路 dp[i][j]表示只用第0 ...

  3. 算法之Python实现 - 002 : 换钱的最少货币数补充(每种货币只能使用一次)

    [题目]:给定数组arr,arr中所有的值都为正数且不重复.每个值代表一种面值的货币,每种面值的货币仅可以使用一张,再给定一个整数aim代表要找的钱数,求组成aim的最少货币数. [代码1]:时间与额 ...

  4. 算法之Python实现 - 001 : 换钱的最少货币数

    [题目]给定数组arr,arr中所有的值都为正数且不重复.每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个整数aim代表要找的钱数,求组成aim的最少货币数. [代码1]:时间与额外 ...

  5. 剑指OFFER之把数组排成最小的数(九度OJ1504)

    题目描述: 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个.例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323. 输入: 输 ...

  6. 九度OJ 1504 把数组排成最小的数【算法】-- 2009年百度面试题

    题目地址:http://ac.jobdu.com/problem.php?pid=1504 题目描述: 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个.例如 ...

  7. 通过设置线程池的最小线程数来提高task的效率,SetMinThreads。

    http://www.cnblogs.com/Charltsing/p/taskpoolthread.html task默认对线程的调度是逐步增加的,连续多次运行并发线程,会提高占用的线程数,而等若干 ...

  8. 《剑指offer》第四十五题(把数组排成最小的数)

    // 面试题45:把数组排成最小的数 // 题目:输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼 // 接出的所有数字中最小的一个.例如输入数组{3, 32, 321},则打印出这3 ...

  9. 《剑指offer》— JavaScript(32)把数组排成最小的数

    把数组排成最小的数 题目描述 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个.例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为3213 ...

随机推荐

  1. CEPH 对象存储的系统池介绍

    RGW抽象来看就是基于rados集群之上的一个rados-client实例. Object和pool简述 Rados集群网上介绍的文章很多,这里就不一一叙述,主要要说明的是object和pool.在r ...

  2. 在一个含有1-n的序列中,每次找到第Ki小的数,并把它删除(线段树)

    提交链接 Data structure is one of the basic skills for Computer Science students, which is a particular ...

  3. IE浏览器主页被篡改为2345,针对一般解决办法无法解决的情况

    1.注册表修改 按微软键+R  输入regedit 弹出注册表.HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN 将右侧的Sta ...

  4. Java虚拟机学习笔记(二)--- 判断对象是否存活

    Java堆中存放着所有的对象实例,垃圾收集器在堆进行回收之前,需要判断对象是“存活”还是“死亡”(即不可能再被任何途径引用的对象). 最常见的一种判断对象是否存活算法是引用计数算法, 给对象加一个引用 ...

  5. Servlet生成验证码并进行账号密码和验证码的验证登陆!

    前言: 人不是生来就懂事的,在编程的世界也是一样,想想在大一的时候我还是那个连输出Hello World!都不会的小孩子是,现在我已经可以编出属于我自己的小程序了.编程其实并不可怕,可怕的是你不去编. ...

  6. mpvue微信小程序项目踩坑记录

    1.mpvue入门教程, http://mpvue.com/mpvue/quickstart.html # . 先检查下 Node.js 是否安装成功 $ node -v v8.9.0 $ npm - ...

  7. 大白话5分钟带你走进人工智能-第32节集成学习之最通俗理解XGBoost原理和过程

    目录 1.回顾: 1.1 有监督学习中的相关概念 1.2  回归树概念 1.3 树的优点 2.怎么训练模型: 2.1 案例引入 2.2 XGBoost目标函数求解 3.XGBoost中正则项的显式表达 ...

  8. API开发之接口安全(三)----sign有效时间

    之前生成的sign和校验sign我们已经完全掌握了.但是仅仅凭借这样的sign是无法满足我们的需求的,如果一个黑客通过抓包抓到你的数据 他可以去修改你的header为这样的 body为那样的 也是可以 ...

  9. 敏捷之旅--携程Scrum Master 新官上任三把火?

      随着敏捷在国内的推行,越来越多的公司和组织开始使用敏捷领导团队. 敏捷团队如雨后春笋之势涌现. 敏捷教练的团队也越来越壮大.   原先只需要一个敏捷教练就能搞定,但是随着团队越来越多,我们难免会将 ...

  10. windows+appium自动化,Desired Capabilities参数填写,查看界面信息

    前言: 安装JDK并配置环境变量. 安装sdk并配置对应环境变量. 安装appium客户端. 手机打开开发者模式,并启用调试模式. 1.打开Appium客户端,点击Start Server V1.9. ...