动态规划--算法 2021.05.15 周六

目录

1.算法模板

 

 


幕布脑图: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(n^{k}), 运行超时

输入的测试用例是

[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中看到。
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值