零钱兑换
给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。
计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1 。
你可以认为每种硬币的数量是无限的。
示例 1:
输入:coins = [1, 2, 5], amount = 11
输出:3
解释:11 = 5 + 5 + 1
记忆化搜索
递归树
将能凑成当前金额,使用的最少硬币个数记录下来
如果重复计算,就直接拿去记忆化数组中的值
class Solution {
public int coinChange(int[] coins, int amount) {
mem = new int[amount+1];
Arrays.fill(mem,-1);
int res = dfs(amount, coins);
return res == 10001 ? -1 : res;
}
int mem[];
int dfs(int rest, int []coins){
if(rest==0) return 0;
if(mem[rest]!=-1) return mem[rest];
int ans = 10001;
for(int coin : coins){
if(rest-coin>=0){
ans = Math.min(dfs(rest-coin, coins)+1,ans);
}
}
mem[rest] = ans; //记忆化
return ans;
}
}
DP的思想
完全背包的思想