【动态规划】不同路径问题:leetcode62和63

62.不同路径

  1. 动态规划
class Solution:
    def uniquePaths(self, m: int, n: int) -> int:
        dp = [[1 for i in range(n)] for j in range(m)]
        for i in range(1,m):
            for j in range(1,n):
                dp[i][j] = dp[i-1][j] + dp[i][j-1]
        return dp[m-1][n-1]
  1. 数论(组合问题)

求解组合 C m + n − 2 m − 1 C_{m+n-2}^{m-1} Cm+n2m1

def main():
    m, n = list(map(int, input().split()))
    deno = m-1   #分母
    nume = 1     #分子初始化为1是为了在while循环中进行第一次计算
    t = m+n-2    #分子相乘的结果用t来保存
    count = m-1  #计算的次数,当count==0时停止计算,初始化为分母
    while count:
        nume*=t
        t-=1
        #这个while循环设置的含义是:只要分子和分母可以约掉,就一直约,然后再
        #乘一个分子继续这样的操作
        while deno!=0 and nume % deno ==0:
            nume = nume/deno
            deno-=1
        count-=1
    print(int(nume))

63.不同路径II

class Solution:
    def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int:
        #1. 获取m和n的值
        m = len(obstacleGrid)
        n = len(obstacleGrid[0])
        #2. 如果在起始点和终止点出现了障碍,则返回0
        if obstacleGrid[0][0]==1 or obstacleGrid[m-1][n-1]==1:
            return 0
        #3.初始化dp数组
        dp = [[0 for _ in range(n)] for _ in range(m)]
        dp[0][0] = 1 if obstacleGrid[0][0]!=1 else 0
        if dp[0][0] ==0:return 0

        #初始化行的时候注意遍历的是列
        for i in range(1,n):
            if obstacleGrid[0][i]!=1:
                dp[0][i] = dp[0][i-1]
            
        #初始化列的时候注意遍历的是行
        for i in range(1,m):
            if obstacleGrid[i][0]!=1:
                dp[i][0] = dp[i-1][0]

        # 本题确定遍历方式为从左到右遍历,对应机器人每次只能向下或向右走
        # dp[i][j]的含义:从[0][0]到[i][j]有dp[i][j]条不同的路径,所以如果obstacleGrid[i][j]==1
        # 则dp[i][j]==0,也即不进行运算,因为原本初始化为0

        #这里需要注意是从1开始遍历
        for i in range(1,m):
            for j in range(1,n):
                if obstacleGrid[i][j]!=1:
                    dp[i][j] = dp[i-1][j]+dp[i][j-1]
        return dp[-1][-1]

你可能感兴趣的:(leetcode,动态规划,算法)