LeetCode 第二十八天 2024.8.14

1. :不同路径 II
 题目链接: 63. 不同路径 II - 力扣(LeetCode)
应用条件:动态规划

难点:

# 确定dp数组(dp table)以及下标的含义:dp[i][j]表示有多少种方法到格子(i,j)

# 确定递推公式: dp[i][j] = dp[i-1][j] + dp[i][j-1]

# dp数组如何初始化:  dp[0][i] = 1 dp[i][0] = 1,在有障碍物的地方都是0,并且dp[0][i]和dp[i][0]在i==0后面所有都是0

# 确定遍历顺序: for i in range(1,m): for j in range(1,n):

# 举例推导dp数组: dp[3][7] = dp[2][7] + dp[3][6]

个人错误:

思路:

class Solution:
    def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int:
        if obstacleGrid[0][0] == 1:
            return 0
        dp = [[0]*len(obstacleGrid[0]) for i in range(len(obstacleGrid))]
        for i in range(len(obstacleGrid[0])):
            if obstacleGrid[0][i] == 1:
                dp[0][i] = 0
                if i+1 < len(obstacleGrid[0]):
                    for j in range(i+1,len(obstacleGrid[0])):
                        dp[0][j] = 0
                break
            else:
                dp[0][i] = 1
        for i in range(len(obstacleGrid)):
            if obstacleGrid[i][0] == 1:
                dp[i][0] = 0
                if i+1 < len(obstacleGrid):
                    for j in range(i+1,len(obstacleGrid)):
                        dp[j][0] = 0
                break
            else:
                dp[i][0] = 1   
        for i in range(1,len(obstacleGrid)):
            for j in range(1,len(obstacleGrid[0])):
                if obstacleGrid[i][j] == 1:
                    dp[i][j] = 0
                else:
                    dp[i][j] = dp[i-1][j] + dp[i][j-1]
        print(dp)
        return dp[len(obstacleGrid)-1][len(obstacleGrid[0])-1]    

2. :整数拆分
 题目链接: 343. 整数拆分 - 力扣(LeetCode)
应用条件:动态规划

难点:

# 确定dp数组(dp table)以及下标的含义:dp[i]表示拆分正整数i得到的最大乘积
# 确定递推公式: 把i拆分成j和i-j dp[i]=max(dp[i],j*(i-j),j*dp[i-j])
# dp数组如何初始化:  dp[0]和dp[1]都是没有意义的,所以从2开始dp[2] = 1
# 确定遍历顺序: for i in range(3,n): for j in range(1,i):
# 举例推导dp数组: dp[5] = max(dp[i],j*(i-j),j*dp[i-j])

个人错误:

思路:

class Solution:
    def integerBreak(self, n: int) -> int:
        dp = [0]*(n+1)
        dp[2] = 1
        if n <2:
            return 0
        if n == 2:
            return 1
        for i in range(3,n+1):
            for j in range(1,i):
                dp[i] = max(dp[i],j*(i-j),j*dp[i-j])
        return dp[n]

3. :不同的二叉搜索树
 题目链接: 96. 不同的二叉搜索树 - 力扣(LeetCode)
应用条件:动态规划

难点:
# 确定dp数组(dp table)以及下标的含义:dp[i]表示i个节点得到的最多二叉搜索树
# 确定递推公式: 用j从1遍历i,表示把j当作头节点的二叉搜索树,dp[i] += dp[j-1]*dp[i-j]
# dp数组如何初始化:  dp[0]和dp[1]都是1
# 确定遍历顺序: for i in range(2,n): for j in range(1,i):
# 举例推导dp数组: dp[5] += dp[j-1]*dp[5-j]

个人错误:

思路:

class Solution:
    def numTrees(self, n: int) -> int:
        dp = [0]*(n+1)
        dp[0] = 1
        dp[1] = 1
        if n<2:
            return 1
        for i in range(2,n+1):
            for j in range(1,i+1):
                dp[i] += dp[j-1]*dp[i-j]
        # print(dp)
        return dp[n]

4. :01背包理论基础
 题目链接: 
应用条件:

难点:

# 确定dp数组(dp table)以及下标的含义:dp[i][j]表示从0-i物品中任取放入容量为j的背包中
# 确定递推公式: 就看这个物品(重量weight[i])放不放进背包里,放不进去直接dp[i][j] = dp[i-1][j] 能放进去看放进去价值大还是不放进去价值大dp[i][j] = max( dp[i-1][j], dp[i-1][j-weight[i]] +value[i])
# dp数组如何初始化: dp[0][j] 应该是 0,因为背包容量比编号0的物品重量还小。当j >= weight[0]时,dp[0][j] 应该是value[0],因为背包容量放足够放编号0物品
# 确定遍历顺序: 先遍历物品,然后遍历背包重量

个人错误:

思路:

n, bagweight = map(int, input().split())

weight = list(map(int, input().split()))
value = list(map(int, input().split()))

dp = [[0] * (bagweight + 1) for _ in range(n)]

for j in range(weight[0], bagweight + 1):
    dp[0][j] = value[0]

for i in range(1, n):
    for j in range(bagweight + 1):
        if j < weight[i]:
            dp[i][j] = dp[i - 1][j]
        else:
            dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i])

print(dp[n - 1][bagweight])

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值