代码随想录算法训练营第三十六天|leetcode1049.最后一块石头的重量II、leetcode494.目标和、leetcode474.一和零

1 leetcode1049.最后一块石头的重量II

题目链接:1049. 最后一块石头的重量 II - 力扣(LeetCode)

文章链接:代码随想录

视频链接:动态规划之背包问题,这个背包最多能装多少?LeetCode:1049.最后一块石头的重量II_哔哩哔哩_bilibili

思路:背包问题的难点,对我而言,就是不明白背包的重量,,就是有不理解的地方

1.1 自己的代码

卡壳:新的卡壳点,不知道如何确定背包的总重量,然后看了视频开头自己就瞬间明白了,真的不是很聪明的样子

class Solution:
    def lastStoneWeightII(self, stones: List[int]) -> int:
        target = sum(stones)//2
        dp = [0]*(target+1)
        dp[0] =0
        for i in range(len(stones)):
            for j in range(target,stones[i]-1,-1):
                dp[j] = max(dp[j],dp[j-stones[i]]+stones[i])
        return sum(stones)-2*dp[-1]

1.2 本题小结

  1. 真的不理解我为什么会卡在不知道如何确定背包的总重量这一个地方,真的还是多练习,不过好消息就是这种题目的思路,我其实还是掌握了的,完全背包
  2. 恭喜自己,又学会了一个新的知识点,继续向下加油吧

2 leetcode494.目标和

题目链接:494. 目标和 - 力扣(LeetCode)

文章链接:代码随想录

视频链接:动态规划之背包问题,装满背包有多少种方法?| LeetCode:494.目标和_哔哩哔哩_bilibili

思路:真的,就是背包问题的变体,我有的时候就想不到,如何将这个数值进行,就是首先就不知道那个值,背包的总重量的确定,就不是很会

2.1 视频后的思路

方法

  1. 定义dp[i][j]的含义,这里是表示的是第i-1个数中得到这个值的种类
  2. 关于递推公式,是通过演化得到的,其实主要问题就是如何确定这个背包的总重量,这一块对我而言有点难吧
  3. 这种题就是边写用其他的运行环境运行一下,看看结果
class Solution:
    def findTargetSumWays(self, nums: List[int], target: int) -> int:
        total_sum = sum(nums)
        if abs(target)>total_sum:
            return 0
        if (total_sum+target)%2 !=0:
            return 0
        target_sum = (total_sum+target)//2
        dp = [[0]*(target_sum+1) for _ in range(len(nums)+1)]
        dp[0][0] = 1
        for i in range(1,len(nums)+1):
            for j in range(target_sum+1):
                if j<nums[i-1]:
                    dp[i][j] = dp[i-1][j]
                else:
                    dp[i][j] = dp[i-1][j]+dp[i-1][j-nums[i-1]]
        return dp[-1][-1]

2.2 一维数组的方法

class Solution:
    def findTargetSumWays(self, nums: List[int], target: int) -> int:
        total_sum = sum(nums)
        if abs(target)>total_sum:
            return 0
        if (total_sum+target)%2 !=0:
            return 0
        target_sum = (total_sum+target)//2
        dp = [0]*(target_sum+1)
        dp[0] = 1

        for i in range(len(nums)):
            for j in range(target_sum,nums[i]-1,-1):
                dp[j] = dp[j] + dp[j-nums[i]]
        return dp[-1]

2.3 本题小结

  1. 这道题目,首先就是如何确定背包的总重量是多少,其实对现在我做背包问题而言,这个更难,第二个才是递推公式的构造
  2. 还是多练习,多去看,虽然现在理解了做这个题目的逻辑吧,但是自己做的时候就容易出错

3 leetcode474.一和零

题目链接:474. 一和零 - 力扣(LeetCode)

文章链接:代码随想录

视频链接:动态规划之背包问题,装满这个背包最多用多少个物品?| LeetCode:474.一和零_哔哩哔哩_bilibili

思路:怎么说呢,有点思路,但是不知道如何统计两个背包的数?这么说可能有点不对,但是我想表达的就是这个意思,还是看看视频吧

3.1 视频后的思路

实话说,背包问题,有些绕对我而言,经常会出一些小的bug

class Solution:
    def findMaxForm(self, strs: List[str], m: int, n: int) -> int:
        dp = [[0]*(n+1) for _ in range(m+1)]
        dp[0][0] = 0
        for s in strs:
            x= 0
            y = 0
            for char in s:
                if char == '0':
                    x+=1
                else:
                    y +=1
            for i in range(m,x-1,-1):
                for j in range(n,y-1,-1):
                    dp[i][j] = max(dp[i][j],dp[i-x][j-y]+1)
        return dp[m][n]

3.2 小改进的地方

使用统计的方法,其实也挺美妙的

class Solution:
    def findMaxForm(self, strs: List[str], m: int, n: int) -> int:
        dp = [[0]*(n+1) for _ in range(m+1)]
        dp[0][0] = 0
        for s in strs:
            zero= s.count('0')
            one = s.count('1')
            for i in range(m,zero-1,-1):
                for j in range(n,one-1,-1):
                    dp[i][j] = max(dp[i][j],dp[i-zero][j-one]+1)
        return dp[m][n]

3.3 本题小结

  1. 这道题目,真的就是很难想到我可以用二维数组就直接表示,就是这里,背包内的物品把我弄着有点难吧,其实其他的就还行
  2. 递推公式其实还是要多练习多去找规律,会比较好一点,继续加油吧

4 今日小结

  1. 动态规划两个点,需要掌握,第一个如何确定背包的总价值是多少,这里会经常写错,递推公式也是会出问题,就是问题有点多吧
  2. 但是好消息是我掌握了背包问题的基本原理,希望接下来会越做越好吧,继续加油就是说
posted @   小方呀0524  阅读(6)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示