一、多维动态规划
1、不同路径
①常规思路
维护一个二维数组f,f[i][j]表示从起点到(i,j)的路径数。
已知初始化f[0][0]=1,即机器人在起点的路径是1;机器人到达第一列f[:][0]只能从上方这一条路走下来,因此第一列的每个元素都为1;机器人到达第一行f[0][:]只能从左方这一条路走下来,因此第一行的每个元素都为1。
状态转移公式:f[i][j]=f[i-1][j]+f[i][j-1],这是因为机器人到达一个点(i,j),只能从上方和左方走过来,因此到达(i,j)的路径之和=到达(i-1,j)的路径总数+到达(i,j-1)的路径总数。
class Solution:
def uniquePaths(self, m: int, n: int) -> int:
f=[[1]*n for _ in range(m)]
for i in range(1,m):
for j in range(1,n):
f[i][j]=f[i-1][j]+f[i][j-1]
return f[m-1][n-1]
②优化空间复杂度
对于上面的二维状态数组而言,当我们遍历到第 i 行时,f[i][j] 的计算只依赖于当前 j 列(也就是 cur[j],对应的是 f[i-1][j] 的值)和 j-1 列(也就是cur[j-1],对应的是 f[i][j-1] 的值)
class Solution:
def uniquePaths(self, m: int, n: int) -> int:
cur=[1]*n
for i in range(1,m):
for j in range(1,n):
cur[j]+=cur[j-1]
return cur[n-1]
2、 最小路径和
对于第一行来说,只能从左往右走;对于第一列来说,只能从上往下走。所以初始化grid[i][0]=grid[i-1][0]+grid[i][0],grid[0][j]=grid[0][j-1]+grid[0][j]。
因为只能向下或向右到达某个位置,因此到达一个位置的最小路径和等于到达其上方位置的最小路径和加当前位置值和到达其左方位置的最小路径和加当前位置值中的最小值。
class Solution:
def minPathSum(self, grid: List[List[int]]) -> int:
if not grid or not grid[0]:
return 0
m,n=len(grid),len(grid[0])
for i in range(1,m):
grid[i][0]=grid[i-1][0]+grid[i][0]
for j in range(1,n):
grid[0][j]=grid[0][j-1]+grid[0][j]
for i in range(1,m):
for j in range(1,n):
grid[i][j]=min(grid[i-1][j]+grid[i][j],grid[i][j-1]+grid[i][j])
return grid[m-1][n-1]
3、最长回文子串
①动态规划
(1)状态数组:维护一个二维数组dp,dp[i][j]表示子串s[i:j+1]是否为回文串,若dp[i][j]为True说明子串s[i:j+1]是为回文串,否则不是。
(2)状态转移方程:①当子串长度为2时(即j=i+1),若有s[i]=s[j],则此时子串s[i:j+1]是为回文串,dp[i][j]=True;②当子串长度大于2时,若有s[i]=s[j],并且该子串内部子串s[i+1:j-1]也是回文串,则当前子串s[i:j+1]也为回文串(举个例子,abba,a=a,bb又是回文串,所以abba也是回文串)。
(3)步骤:
- 判断串s是否为空串,若为空则返回空串。
- 判断串s是否长度为1,若长度唯一,则一定是回文串,返回s即可。
- 初始化dp数组除了dp[i][i]以外全部为False(这是因为dp[i][i]表明的是字符串中的单个字符

多维动态规划&spm=1001.2101.3001.5002&articleId=142032069&d=1&t=3&u=64d2556d31af48ed89caae78ad6521bd)
1325

被折叠的 条评论
为什么被折叠?



