题目描述:给定数组arr,arr中所有的值都为正整数且不重复。每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个aim,代表要找的钱数,求组成aim的最少货币数。如果无解,请返回-1.
示例
输入:[5,2,3],20
返回值:4,最少需要四张5才能组成20
输入:[5,2,3],0
返回值:0,可以一张不取。
输入:[3,5],2
返回值:-1,没办法组成2
思路:使用一个dp数组存放组成每一面值的最少货币数,数组大小为aim+1,dp数组初始值全为-1;
以[5,2,3],20为例。
初始化数组,int[] dp = new int[21];:
dp[0]=0;
dp[2]=1;
dp[3]=1;
dp[5]=1;
然后根据初始值逐个给dp[i]赋值
dp[1]=min{dp[-4]+1,dp[-1]+1,dp[-2]+1},因为dp[-1],dp[-2],dp[-4],都不存在,所以dp[1]的值无法更新,还是-1,即无法组成面值为1的情况。
dp[4]=min{dp[-1]+1,dp[2]+1,dp[1]+1},因为dp[-1]不存在,dp[1]=-1,所以只有dp[2]一个有效值,更新dp[4]=dp[2]+1=2
dp[6]=min{dp[1]+1,dp[4]+1,dp[3]+1},因为dp[1]=-1,所以有dp[3]、dp[4]两个有效值,更新dp[6]=min{1+1,2+1}=2;
dp[7]=min{dp[2]+1,dp[5]+1,dp[4]+1},dp[2]、dp[5]、dp[4]均为有效值,所以更新dp[7]=min{1+1,1+1,2+1}=2。
之后依此类推,直到计算出dp[aim];
注意!!!也就是说,只有当dp[i]的下标i有效(i>=0)且dp[i]!=-1时,才是有效值,才可以更新数据。
代码实现:
import java.util.*;
public class Solution {
public int minMoney (int[] arr, int aim) {
// write code here
Arrays.sort(arr);
if(aim==0){
return 0;
}else if(arr.length==0||arr==null||aim=0 && dp[i-arr[j]]!=-1){
if(dp[i]==-1){
dp[i] =dp[i-arr[j]]+1;
}else{
dp[i] = Math.min(dp[i-arr[j]]+1,dp[i]);
}
}
}
}
}
return dp[aim];
}
}

![[NC126]换钱的最少货币数(Java实现) [NC126]换钱的最少货币数(Java实现)](http://www.mshxw.com/aiimages/31/287230.png)
