动态规划_路径的数目

动态规划 Dynamic Programming

“Simplifying a complicated problem by breaking it down into simpler subproblems” (in a recursive manner)

Divide & Conquer + Optimal substructure

关键点:
动态规划和递归或者分治没有根本上的区别(关键看有无最优子结构)
共性:找到重复子问题
差异性:最优子结构、中途可以淘汰次优解

动态规划 关键点:
1、最优子结构 opt[n] = best_of(opt[n-1],opt[n-2],…)
2、储存中间状态:opt[i]
3、递推公式(美其名曰:状态转移方程或者DP方程)
Fib:opt[i] = opt[n-1] + opt[n-2]
二维路径:opt[i,j] = opt[i+1][j] + opt[i][j+1] (且判断a[i,j]是否为空地)

剑指offer 98.路径的数目
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。
问总共有多少条不同的路径?
在这里插入图片描述
输入:m = 3, n = 7
输出:28

解法一:动态规划,写出状态转移方程dp[i][j] = dp[i-1][j] + dp[i][j-1]

class Solution:
    def uniquePaths(self, m: int, n: int) -> int:
        dp = [[0]* n for _ in range(m)]
		# 将第0行第0列都初始化为1
        for j  in range(n):
            dp[0][j] = 1
        for i in range(m):
            dp[i][0] = 1
		
		# 两层循环遍历
        for j in range(1,n):
            for i in range(1,m):
                dp[i][j] = dp[i][j-1] + dp[i-1][j]
        
        return dp[m-1][n-1]

解法二:排列组合
这道题只能向右或者向左,说明只会有两种情况

那么分析这道题

1、向右的数量和向下的数量的和是一定的
2、向右和向下的没什么区别
1)如果我们边长为 m,n,则有(m - 1)个向右 , (n - 1 )个向下得到最终的结果
2)转化为 有 (m-1) 个向下 ,我们需要把( n - 1)个向右插入向下中,
注:因为m -1 有头尾 则有m个间隙
3)转化为 高中做过的竞赛题 (n - 1) 个乒乓球 插入到编号为 (1到m) m个洞中,洞可以为空
4)转化为 有(n+m - 1) 个乒乓球 我们需要把它放入m个洞中,每个洞最少放一个
5)转化为 有 (n+m - 2) 个乒乓球间隙,放入 m -1 个挡板,把球分成m份,每份不能为空

那么得到我们最终的公式
在这里插入图片描述
代码:

class Solution:
    def uniquePaths(self, m: int, n: int) -> int:
        res = 1 
        x = n 
        y = 1

        while x <= n + m -2:
            res = res * x // y
            x += 1 
            y += 1
        
        return res 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值