算法学习(十六)

学习内容:

动态规划算法:每次决策依赖于当前状态,又随即引起状态的转移。一个决策序列就是在变化的状态中产生出来的,所以,这种多阶段最优化决策解决问题的过程就称为动态规划。
在查找有很多重叠子问题的情况的最优解有效。动态规划保存子问题的解,避免重复计算。

学习产出:

背包问题:一种组合优化的NP完全问题;0-1背包对物品迭代放外层,里层体积或价值逆向遍历;完全背包物品迭代放里层,外层体积或价值正向遍历

动态规划

解决动态规划问题的关键是找到状态转移方程,这样就可以通过计算和存储子问题的解来解决最终问题。

LeetCode416 分割等和子集

给定一个只包含正整数的非空数组。是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。

注意:

每个数组中的元素不会超过 100
数组的大小不会超过 200

示例 1:

输入: [1, 5, 11, 5]

输出: true

解释: 数组可以分割成 [1, 5, 5][11].
         
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/partition-equal-subset-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解

0-1背包问题,设数字总和为sum,我们的目标选取一部分物品是的总和sum/2.由于不需要考虑价值,因此布尔矩阵表示状态转移矩阵

代码(python)

class Solution:
    def canPartition(self, nums: List[int]) -> bool:
        accumulate = sum(nums)
        target, n = accumulate//2,len(nums)
        if accumulate % 2: return False
        dp = [False]*(target+1)
        dp[0] = True
        for i in range(1,n+1):
            for j in range(target,nums[i-1]-1,-1):
                dp[j] = dp[j] or dp[j-nums[i-1]]
        return dp[target]
        

LeetCode322 零钱兑换

给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。

你可以认为每种硬币的数量是无限的。

示例 1:

输入:coins = [1, 2, 5], amount = 11
输出:3 
解释:11 = 5 + 5 + 1


来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/coin-change
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    

题解

完全背包问题,定义dp[j]表示填满容量为j的背包最少需要多少硬币,状态转移方程:dp[j] = min(dp[j], dp[j - coin] + 1)即当前填满容量j最少需要的硬币 = min( 之前填满容量j最少需要的硬币, 填满容量 j - coin 需要的硬币 + 1个当前硬币)
注意初始化:amount+2矩阵,因为有求最小值,赋值-1会导致结果为-1,同时amount+2大于所有可能组合方式

代码(python)

class Solution:
    def coinChange(self, coins: List[int], amount: int) -> int:
        dp = [amount+2]*(amount+1)
        dp[0] = 0
        for i in range(1,amount+1):
            for coin in coins:
                if i >= coin:
                    dp[i] = min(dp[i],dp[i-coin]+1)
        if dp[amount] == amount+2:
            return -1
        else:
            return dp[amount]
        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值