硬币找零问题从暴力搜索到动态递归
问题描述:给定一组硬币面值(例如(5,10,2,1)),和一个目标金额(例如100),每种面值的硬币数量不限,求有多少种组成目标金额的方式。
问题抽象为数学问题:给定一个数组arr={5,10,2,1},和目标金额aim=100,使用数组中的元素任意次组成目标金额aim的方法有多少种。
暴力搜索
使用{5,10,2,1}任意组合成100的方法有以下几种情况:
1.使用0张5,其余{10,2,1}任意组合成100
2.使用1张5,其余{10,2,1}任意组合成95
.
.
.
21.使用20张5,其余{10,2,1}任意组合成0
所以题目中的方法数是以上21种情况的方法数之和,采用暴力搜索的递归解法如下(java实现)
/**
* 暴力搜索的递归实现
* @param arr
* @param aim
*/
public static int coin1(int[] arr,int aim){
if(arr==null || arr.length==0 || aim<0){
return 0;
}
return getCoinProcess(arr,0,aim);
}
/**
* @param arr
* @param i 组成范围是从数组中的i到arr.length-1
* @param aim 组和的目标金额是aim
* @return
*/
private static int getCoinProcess(int[] arr, int i, int aim) {
int res=0;
if(i==arr.length && aim==0){
res=1;
}else if(i==arr.length && aim!=0){
res=0;
}else{
//s为最多会用到的arr[i]的数量,例如在在本例中对于arr[0]最多会用20张
int s=aim