最长公共子串 和 最长公共子序列

子串必须连续, 子序列不要求连续,次序不变即可

最长公共子串

dp[i][j] 表示以A[i]为结尾的A 的子串 和 以B[i]为结尾的B 的子串的 最长公共子串的长度
初始化:

if A[0] == B[0]:
  dp[0][0] = 1
else: 
  dp[0][0] = 0

转移公式:

if A[i] == B[i]: 
  dp[i][j] = dp[i-1][j-1] + 1
else:
  dp[i][j] = 0

要求的结果 max(dp)

最长公共子序列

dp[i][j] 表示 A[0:i](即以A[i-1]为结尾, 包括A[i-1])和 B[0:j] 的最长公共子序列的长度
初始化:

dp[i][0] = 0
dp[0][j] = 0

转移公式:

if A[i] == B[j]:
  dp[i][j] = dp[i-1][j-1] + 1
else:
   dp[i][j] = max(dp[i-1][j], dp[i][j-1])

返回值: dp[len(A)-1][len(B)-1]

最长连续递增子序列和最长递增子序列

最长连续递增子序列

dp[i] 表示以下标i为结尾的数组的连续递增子序列的长度
初始化:

dp[i] = 1 for i in range(len(nums)+1)

转移公式:

if nums[i+1] > nums[i]:
  dp[i+1] = dp[i] +1

返回值:max(dp)

最长递增子序列

dp[i] 表示下标i之前(包括下标i)的最长递增子序列的长度
初始化:

dp[i] = 1 for i in range(len(nums))

转移公式:

for i in range(1, len(nums)):
  for j in range(i):
    if nums[i]>nums[j]:
      dp[i] = max(dp[i], dp[j]+1)

返回值: max(dp)

回文子串和最长回文子序列

回文子串

给定一个字符串,统计该字符串有多少个回文子串
dp[i][j]= True 表示i和j之间的字符串(左闭右闭)是回文子串
初始化:

dp[i][j] = False

转移公式:

if s[i] == s[j]:
  if j-i <= 1:
    dp[i][j] = True
    cnt+=1
  else:
    dp[i][j] = dp[i+1][j-1]
    cnt+=1

返回值:cnt

最长回文子序列

dp[i][j] 表示字符串在i 到j (包括j)区间最长回文子序列的长度
初始化:

dp[i][j] = 1

转移公式:

if s[i] == s[j]:
  dp[i][j] = dp[i+1][j-1] +2

返回值:
dp[0][-1]