【算法入门】浅谈动态规划

这篇具有很好参考价值的文章主要介绍了【算法入门】浅谈动态规划。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

动态规划引言

关于动态规划的定义,网上有很多,但对于初学者,看了定义之后,多少会有点懵,接下来我打算用俩到三个例题来引入动态规划的定义,我将动态规划分为动态和规划俩部分,动态说明它是变化的,规划说明它是从前到后的,所以综合下来就是后面的由前面或者说受前面影响。

案例分析

1.爬楼梯

题目联接:link
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

示例 1:

输入:n = 2
输出:2
解释:有两种方法可以爬到楼顶。

  1. 1 阶 + 1 阶
  2. 2 阶
    示例 2:

输入:n = 3
输出:3
解释:有三种方法可以爬到楼顶。
3. 1 阶 + 1 阶 + 1 阶
4. 1 阶 + 2 阶
5. 2 阶 + 1 阶
我们仔细分析:
台阶数n:
当n = 4 有5种方法可以爬到楼梯
1阶+1阶+1阶+1阶
1阶+1阶+2阶
1阶+2阶+1阶
2阶+1阶+1阶
2阶+2阶
当n = 5时,有8种方法可以爬到楼梯
1阶+1阶+1阶+1阶+1阶
1阶+1阶+1阶+2阶
1阶+1阶+2阶+1阶
1阶+2阶+1阶+1阶
2阶+1阶+1阶+1阶
2阶+2阶+1阶
2阶+1阶+2阶
1阶+2阶+2阶
我们会发现到达第n阶的方法数等于到达第n-1阶和到达第n-2阶的方法数之和,并且从另一个角度分析,要爬到第n阶楼梯,(由于一次只能跳1级或2级)所以只有从第n-1级台阶或者是第n-2级台阶才能跳到第n级台阶,而第n-1级台阶又只能由n-1级台阶的前俩级台阶跳到,之后也是如此,直到第二级台阶。(关系)
所以当台阶数n>2时,count(n)= count(n-1)+count(n-2)
(count是方法数量)
接下来我们有俩种处理方法:
第一种,首先,我们对第一级和第二级台阶进行初始化,令a = 1表示第一级台阶的方法数,b = 2表示第二台阶的方法数,之后根据他们之间的关系进行求解。
python代码1如下:(自底向上)

a = 1 #第一级台阶方法数
b = 2 #第二级台阶方法数
n = int(input()) 
i = 3 #我们从第三级台阶开始求解
count = 0 #第n级台阶的方法数
while i<=n:
	count = a+b #后一级台阶数等于前俩级台阶数之和
  a = b  
  b = count
  i += 1
print(count)

python代码2如下:(自顶向下)

def count(n):
	if n == 1:
    	return 1
	elif n == 2:
   		return 2
	else:
    	return count(n-1)+count(n-2)

#主代码
n = int(input())
print(count(n)) #调用函数

俩种写法都可以:但都各有缺点,写法1:当n=1或2时,需要另作处理,写法2:时间复杂度大,为O(2^n),且当n较大时,可能消耗的栈帧可能会导致溢出。

第二种就是动态规划的通用方法:

第一步:先分析,找到关系
第二步:创建一个数组并初始化,就拿爬楼梯来说,当n>2之后,count(n)= count(n-1)+count(n-2),我们可以用一个数组来存储之后求解的值。我们可以创建一个长度为n的数组dp,将dp【0】=1,dp【1】= 2,这样就完成第二步了
第三步:开始求解
我们从下标为2开始求解,直到解完n-1为止,所以存储的dp【n-1】即为我们的解,这里需要提一点:关于dp的创建有俩种,第一种是创建长度为n的dp数组,我们将dp【0】=1,dp【1】= 2,这样初始化,下标0的值就是第一级台阶,下标为1就是第二级台阶,所以第n级台阶的下标是n-1,所以我们求解的结果会存放在dp【n-1】里面
第二种是创建长度为n+1的数组arr,相应地,初始化就要跟着变,arr【0】 = 0,arr【1】= 1,arr【2】 = 2,下标为1表示第一级台阶,下标为2表示第二级台阶,所以第n级台阶下标为n,所以求解结果会存放在arr【n】里面。

python代码如下:

n = int(input())
dp = [0]*n
dp[0] = 1
dp[1] = 2
for i in range(2,n):
	dp[i] = dp[i-1]+dp[i-2]
print(dp[n-1])

缺点是当n<=2时,需要另作处理。

2.编辑距离

题目链接: link

给你两个单词 word1 和 word2, 请返回将 word1 转换成 word2 所使用的最少操作数 。

你可以对一个单词进行如下三种操作:

插入一个字符
删除一个字符
替换一个字符

示例 1:

输入:word1 = “horse”, word2 = “ros”
输出:3
解释:
horse -> rorse (将 ‘h’ 替换为 ‘r’)
rorse -> rose (删除 ‘r’)
rose -> ros (删除 ‘e’)
示例 2:

输入:word1 = “intention”, word2 = “execution”
输出:5
解释:
intention -> inention (删除 ‘t’)
inention -> enention (将 ‘i’ 替换为 ‘e’)
enention -> exention (将 ‘n’ 替换为 ‘x’)
exention -> exection (将 ‘n’ 替换为 ‘c’)
exection -> execution (插入 ‘u’)

第一步:先分析,我们接下来拿word1 = horse和word2 = ros来讲解,我们可以对字符串进行增、删,替三种操作,并且要保证操作次数最少,并且相同字符的位置可能不同,如horse中的r在第三位,而ros中的r在第一位,所以,种种原因,普通方法很难做出正确的代码,(我试过,但最后得到的并不能保证最少次数),所以这题我会用动态规划来讲解。

先来看一张图,上面一行第一个0表示没有字符,然后我们动态地看,看第二个h,从没有字符到一个字符h,我们需要插入字符h,操作次数加一,再看第三个o,从h到ho我们还需要插入一个字符o,操作次数再加一,后面依旧如此,所以增操作,就等价于dp[i] = dp[i-1]+1,下面一行内的数字,代表变成这样需要的操作次数,如下面一行的5表示从没有字符到horse,需要5次操作。所以我们可以建一个 数组来储存操作次数。【算法入门】浅谈动态规划,算法,动态规划,python
但将俩个字符串放在一起看,需要用二维数组来处理,我们建这样的一个二维数组dp来存储操作次数,然后行和列一起看。
【算法入门】浅谈动态规划,算法,动态规划,python
对于dp[1][1]行是r,列是h,对应俩个字符串的第一个字符,我们先判断这俩个字符相不相等,相等,不做处理,进入下一个,对应地,dp[i][j] = dp[i-1][j-1],如果不相等,就需要进行增,删,替操作,
1)、如果把字符 word1[i] 替换成与 word2[j] 相等,则有 dp[i] [j] = dp[i-1] [j-1] + 1;

(2)、如果在字符串 word1末尾插入一个与 word2[j] 相等的字符,则有 dp[i] [j] = dp[i] [j-1] + 1;

(3)、如果把字符 word1[i] 删除,则有 dp[i] [j] = dp[i-1] [j] + 1;

那么我们应该选择一种操作,使得 dp[i] [j] 的值最小,显然有

dp[i] [j] = min(dp[i-1] [j-1],dp[i] [j-1],dp[[i-1] [j]]) + 1;
需要说明的是增和删操作其实可以互换
python代码如下:

class Solution:
    def minDistance(self, word1: str, word2: str) -> int:
        # 建二维数组,长度需要加1
        dp = [[0] * (len(word2) + 1) for _ in range(len(word1) + 1)]
        #dp = [[0]*(len(word2)+1)]*(len(word1)+1)
        #初始化行和列
        for i in range(len(word1) + 1):
            dp[i][0] = i
        for j in range(len(word2) + 1):
            dp[0][j] = j
        # 从dp[1][1]开始求解
        for i in range(1, len(word1) + 1):
            for j in range(1, len(word2) + 1):
                if word1[i - 1] == word2[j - 1]: # 由于下标从1,1开始,所以这里是word1[i - 1]
                    dp[i][j] = dp[i - 1][j - 1]
                else:
                    # 判断最小,因为进行了一次操作,所以后面要加1
                    dp[i][j] = min(dp[i - 1][j - 1], dp[i - 1][j], dp[i][j - 1]) + 1
        # return dp[len(word1)][len(word2)]       也可以
        return dp[-1][-1]



word1 = 'horse'
word2 = 'ros'
a = Solution()
d = a.minDistance(word1,word2)
print(d)

总结

我们再次看动态规划引言,会有更多的理解,动态规划概念如下:
动态规划把多阶段过程转化为一系列单阶段问题,利用各阶段之间的关系,逐个求解,创立了解决这类过程优化问题的新方法–动态规划。
该篇文章旨在帮助理解初学者,让初学者对动态规划有一个大概的理解和认识。可能会有很多地方讲解的不好,还望理解。文章来源地址https://www.toymoban.com/news/detail-848932.html

到了这里,关于【算法入门】浅谈动态规划的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【算法】一文带你快速入门动态规划算法以及动规中的空间优化

    君兮_的个人主页 即使走的再远,也勿忘启程时的初心 C/C++ 游戏开发 Hello,米娜桑们,这里是君兮_,如果给算法的难度和复杂度排一个排名,那么动态规划算法一定名列前茅。在最开始没有什么整体的方法的时候,我也曾经被动态规划折磨过很长时间,通过我一段时间的刷题

    2024年02月05日
    浏览(36)
  • 用python实现动态规划算法

    动态规划(Dynamic Programming,DP)是一种常用的算法思想,通常用于解决具有重叠子问题和最优子结构性质的问题。动态规划算法通常是将问题分解为子问题,先解决子问题,再由子问题的解推导出原问题的解。 动态规划算法的基本步骤如下: 确定状态:定义状态变量,表示

    2024年02月07日
    浏览(26)
  • Leetcode题解-算法-动态规划(python版)

    1.1 爬楼梯 70. 爬楼梯(Easy) 走n阶楼梯的方法有两种,1、先走 1 级台阶,再走 n-1 级台阶;2、先走 2 级台阶,再走 n-2 级台阶 f(n) = f(n-1) + f(n-2) 1.2 强盗抢劫 198. 打家劫舍(Medium) 每个房间财产为 nums[0]……nums[n-1]。 假设 0 至 x 间房获得的最大财产为 f(x)。 f(x) = max(f(x-1),f(x-2)+nums[

    2024年02月03日
    浏览(39)
  • python算法与数据结构---动态规划

    记不住过去的人,注定要重蹈覆辙。 对于一个模型为n的问题,将其分解为k个规模较小的子问题(阶段),按顺序求解子问题,前一子问题的解,为后一子问题提供有用的信息。在求解任一子问题时,通过决策求得局部最优解,依次解决各子问题。最后通过简单的判断,得到

    2024年02月20日
    浏览(40)
  • 【Python算法】实验12-动态规划与背包问题

    目录 实验内容 1.数塔dp -A 2.骨牌铺方格 3.一只小蜜蜂

    2024年02月15日
    浏览(31)
  • 【Python算法】实验8-动态规划与背包问题

    目录 实验内容 1.数塔dp -A 2.骨牌铺方格 3.一只小蜜蜂

    2023年04月19日
    浏览(43)
  • 动态规划的算法题以及其python实现

    动态规划(Dynamic Programming)是一种常用的算法设计技术,用于解决具有最优子结构性质和重叠子问题的问题。它通过将原问题分解为若干个子问题,并先求解子问题的最优解,然后利用子问题的最优解构建原问题的最优解。 动态规划算法通常包括以下几个 关键步骤 : 定义

    2024年02月07日
    浏览(26)
  • Python 算法基础篇:背包问题的动态规划解法

    背包问题是计算机科学中一个重要的组合优化问题,动态规划是解决该问题的高效算法技术。本篇博客将重点介绍背包问题的动态规划解法,包括状

    2024年02月16日
    浏览(31)
  • 算法练习Day30 (Leetcode/Python-动态规划)

    62. Unique Paths There is a robot on an  m x n  grid. The robot is initially located at the  top-left corner  (i.e.,  grid[0][0] ). The robot tries to move to the  bottom-right corner  (i.e.,  grid[m - 1][n - 1] ). The robot can only move either down or right at any point in time. Given the two integers  m  and  n , return  the number of possible

    2024年01月20日
    浏览(34)
  • ​Python—数据结构与算法​---动态规划—DP算法(Dynamic Programing)

    目录 我们一路奋战, 不是为了改变世界, 而是为了不让世界改变我们。 动态规划——DP算法(Dynamic Programing) 一、🏔斐波那契数列(递归VS动态规划) 1、🐒斐波那契数列——递归实现(python语言)——自顶向下 2、🐒斐波那契数列——动态规划实现(python语言)——自底

    2024年02月10日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包