目录
幕布脑图:https://mubu.com/app/edit/recent/4TO7gZxFoM#m
1.算法模板
#初始化base case
dp[0][0][...] = base case
#进行状态转移
for 状态1 in 状态1的所有取值:
for 状态2 in 状态2的所有取值:
for ...
dp[状态1][状态2][...] = 求最值(选择1, 选择2, ...)
2.leecode-322 零钱兑换
https://leetcode-cn.com/problems/coin-change/
2.1) 暴力解法
时间复杂度O(), 运行超时
输入的测试用例是
[1,2,5]
100
class Solution:
def coinChange(self, coins: List[int], amount: int) -> int:
def dp(n):
# base case
if n == 0: return 0
if n < 0: return -1
# 求最小值,所以初始化为正无穷
res = float('INF')
for coin in coins:
subproblem = dp(n - coin)
# 子问题无解,跳过
if subproblem == -1: continue
res = min(res, 1 + subproblem)
return res if res != float('INF') else -1
return dp(amount)
2.2)《labuladong的算法小抄》中给的解答,带“备忘录”的递归
class Solution:
def coinChange(self, coins: List[int], amount: int) -> int:
# 备忘录
memo = dict()
def dp(n):
# 查 "备忘录",避免重复计算
if n in memo : return memo[n]
# base case
if n == 0: return 0
if n < 0: return -1
# 求最小值,所以初始化为正无穷
res = float('INF')
for coin in coins:
subproblem = dp(n - coin)
# 子问题无解,跳过
if subproblem == -1: continue
res = min(res, 1 + subproblem)
# 记入备忘录
memo[n] = res if res != float('INF') else -1
return memo[n]
return dp(amount)
2.3)《labuladong的算法小抄》中给的解答,dp数组的迭代算法
class Solution {
public:
int coinChange(vector<int>& coins, int amount) {
// 数组大小和初始值都是 amount + 1
vector<int> dp(amount + 1, amount + 1);
// base case
dp[0] = 0;
// 外层for循环遍历所有状态的所有取值
for(int i = 0; i < dp.size(); i++){
// 内层循环求所有选择的最小值
for(int coin : coins){
// 子问题无解,跳过
if(i - coin < 0) continue;
dp[i] = min(dp[i], 1 + dp[i - coin]);
}
}
return (dp[amount] == amount + 1) ? -1 : dp[amount];
}
};
将中的收藏导入收趣
收趣
- 注意:
- 1.导入时请不要关闭页面,如果您的要导入的书签较多,请耐心等待
- 2.一旦看到导入完成,您的书签就已保存在收趣,但仍需要一段时间解析后才能在App中看到。
已经导入条,确定要取消?
导入到收趣