简单编程题目连载(四)——找零钱
2017-01-15 11:48
218 查看
经典动态规划题目的暴力求解方法
题目:
有数组penny,penny中所有的值都为正数且不重复。每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个整数aim(小于等于1000)代表要找的钱数,求换钱有多少种方法。
给定数组penny及它的大小(小于等于50),同时给定一个整数aim,请返回有多少种方法可以凑成aim。
测试样例:
输入:
[1,2,4],3,3
输出:
返回:2
这是一道非常经典的动态规划题目,但是直接使用动态规划求解会让初学者很不理解其中的原理,所以将这道题目分别使用暴力搜索方法,记忆搜索方法,动态规划方法以及继续化简后的动态规划方法。这次先来进行最简单的暴力求解方法。
思路是这样的:
使用0张penny[0]面值,用后续面值凑够整数aim的方法有A0种。
使用1张penny[0]面值,用后续面值凑够整数aim的方法有A1种。
使用2张penny[0]面值,用后续面值凑够整数aim的方法有A2种。
使用3张penny[0]面值,用后续面值凑够整数aim的方法有A3种。
…
使用N张penny[0]面值(N*penny[1]<=aim),用后续面值凑够整数aim的方法有An种。
而每一个A种方法都是进行递归求解,即就是使用0张penny[0]面值,使用0张penny[1]面值,用后续面值凑够整数aim的方法有B0种。以此类推。一个标准的递归过程,递归基为当达到目标aim,或超过目标aim。
以下为代码
题目:
有数组penny,penny中所有的值都为正数且不重复。每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个整数aim(小于等于1000)代表要找的钱数,求换钱有多少种方法。
给定数组penny及它的大小(小于等于50),同时给定一个整数aim,请返回有多少种方法可以凑成aim。
测试样例:
输入:
[1,2,4],3,3
输出:
返回:2
这是一道非常经典的动态规划题目,但是直接使用动态规划求解会让初学者很不理解其中的原理,所以将这道题目分别使用暴力搜索方法,记忆搜索方法,动态规划方法以及继续化简后的动态规划方法。这次先来进行最简单的暴力求解方法。
思路是这样的:
使用0张penny[0]面值,用后续面值凑够整数aim的方法有A0种。
使用1张penny[0]面值,用后续面值凑够整数aim的方法有A1种。
使用2张penny[0]面值,用后续面值凑够整数aim的方法有A2种。
使用3张penny[0]面值,用后续面值凑够整数aim的方法有A3种。
…
使用N张penny[0]面值(N*penny[1]<=aim),用后续面值凑够整数aim的方法有An种。
而每一个A种方法都是进行递归求解,即就是使用0张penny[0]面值,使用0张penny[1]面值,用后续面值凑够整数aim的方法有B0种。以此类推。一个标准的递归过程,递归基为当达到目标aim,或超过目标aim。
以下为代码
//penny为待使用数组,n为数组长度,aim为凑整目标数额 public int countWays(int[] penny,int n,int aim){ //当数组为空或者输入数组长度非法或者目标数额小于等于0时,没有结果,直接返回即可 if(penny == null || n <= 0 || aim <= 0){ return 0; } //index从0开始,即从第一张面值起开始计算循环递归 res(penny,0,aim); } //本函数执行递归操作。penny为待使用数组,index为待使用面额(数组下标),aim为后续每次需要到达的目标金额 publi 4000 c int res(int[] penny,int index,int aim){ //定义结果数变量,初始化为0 int result = 0; //这条语句的理解建立在先理解下方for循环的基础之上。就是说每当有一组值凑够了目标数额,就意味着是一种成功的方法。 result = aim == 0 ? 1 : 0; //for循环的循环出口为 index不能超过数组下标,当前面值数额不能超过目标数额,当前需要存在目标数额。 for(int i = 0; index < penny.length && penny[index]*i <= aim && aim > 0; i++){ //进行每一步的递归循环 每次循环的数额为减去已使用面值*数量的新产生的数额 result += res(penny,index+1,aim - penny[index]*i); } return result; }
相关文章推荐
- 简单编程题目连载(六)——找零钱
- 简单编程题目连载(五)——找零钱
- 简单编程题目连载(一)
- 简单编程题目连载(十二)——最优编辑问题
- 简单编程题目连载(十一)——0-1背包问题
- 简单编程题目连载(三)
- 简单编程题目连载(十)——公共最长子序列
- 简单编程题目连载(十三)——拓扑结构相同子树判断
- 简单编程题目连载(七)——经典台阶问题
- 简单编程题目连载(八)——最短路径问题
- 简单编程题目连载(十五)——找二叉树中的最大搜索二叉子树
- 简单编程题目连载(二)
- PAT基础编程题目集 4-8 简单阶乘计算
- 一道简单的编程题目
- 串的简单处理 在实际的开发工作中,对字符串的处理是最常见的编程任务。 本题目即是要求程序对用户输入的串进行处理。
- 编程题目的简单练习
- 简单GUI编程题目
- PAT 基础编程题目集 4-1 简单输出整数
- DE1-SoC初学者——PL部分编程实录——简单LED——连载01(图片上传失败,重新做图中...)
- 微软编程之美的资格赛,这么简单的题目害我编了一个多小时——传话游戏