Maxn = 1005
dp = [[0 for _ in range(Maxn)] for _ in range(Maxn)]
if __name__ == '__main__':
n,m=map(int,input().split())
a= list(map(int,input().split()))
b= list(map(int,input().split()))
for i in range(len(a)):
for j in range(len(b)):
if a[i] == b[j]:
dp[i + 1][j + 1] = dp[i][j] + 1
else:
dp[i + 1][j + 1] = max(dp[i + 1][j], dp[i][j + 1])
print(dp[n][m])
maxn=1005
dp=[1 for _ in range(maxn)]
n=int(input())
a=list(map(int,input().split()))
ans=1
for i in range(len(a)):
for j in range(i):
if a[i]>a[j]:
dp[i]=max(dp[j]+1,dp[i])
ans=max(ans,dp[i])
print(ans)
def to(u):
ans=[]
s=""
for i in u:
if "A"<=i<="Z":
ans.append(s)
s=i
else:
s+=i
ans.append(s)
return ans[1:]#把最一开始的那个”“删除
a=input()
b=input()
a=to(a)
b=to(b)
# print(a)
# print(b)
n,m=len(a),len(b)
dp=[[0 for i in range(m+5)]for j in range(n+5)]
for i in range(len(a)):
for j in range(len(b)):
if a[i]==b[j]:
dp[i+1][j+1]=dp[i][j]+1
else:
dp[i+1][j+1]=max(dp[i+1][j],dp[i][j+1])
print(dp[n][m])
这个类型就做编辑距离,可以通过 DFS 解决,也可以通过 DP 解决。
DP 的时间复杂度低。
我们先来讲一下,编辑距离。
编辑距离为两个字符串,a 和 b 通过多少次变换,使得 a 变成 b。
我们可以做出 3 种操作。
1、删除操作,将 a[i] 从 a 中移除
2、插入操作,在 a[i] 后加上 b[j]
3、替换操作,将 a[i] 修改为 b[j]
编辑距离的状态转移类似 LCS ,但有有很大的差别。
初始状态,i=j=0,都在字符串的开头。
然后开始判断 a[i]=?b[j]
如果相同,那么就不需要修改,所以dp[i+1][j+1]=dp[i][j]
所以在a[i-1]等于b[j-1]时,dp[i][j]这个状态由dp[i-1][j-1]转移而来。
dp[i][j]=dp[i-1][j-1]
如果不同,那就需要进行三种可能的操作
1、修改操作:
a[i] 修改为 b[j], 因为编辑了一次,所以+1
dp[i+1][j+1]=dp[i][j]+1
所以在a[i-1]不等于b[j-1]时,dp[i][j]这个状态由dp[i-1][j-1]转移而来。
dp[i][j]=dp[i-1][j-1]
2、删除操作,直接把 a[i] 删除,此时转移到 dp[i][j+1] ,因为 a[i] 被删除,但是下一个字符到了 a[i] 的位置,而对应比较的位置到了b[j+1]。
所以此时状态转移到了dp[i][j+1]
dp[i][j+1]=dp[i][j]+1
因为编辑了一次,所以+1
所以在a[i-1]不等于b[j-1]时,dp[i][j]就有可能通过dp[i-1][j]转移而来。
3、插入操作,在a[i]后添加一个b[j],那么此时a[i+1]和b[j]对应,因为加了一个字符就变成了a[i+1],而且跟b[j]对应,那么下一个状态转移到了dp[i+1][j]
dp[i+1][j]=dp[i][j]+1
此时状态转移到了 dp[i+1][j]=dp[i][j]+1
因为编辑了一次,所以+1
所以在a[i-1]不等于b[j-1]时,dp[i][j]就有可能通过dp[i][j-1]转移而来。
那么不同时,我们选择他们的最小值即可。
def init(s,t):
dp = [[0 for i in range(len(t) + 1)] for j in range(len(s) + 1)]
for i in range(len(s) + 1):
dp[i][0] = 0
for j in range(1,len(t) + 1):
dp[0][j] = 999999
return dp
if __name__ == '__main__':
s = list(input())
t = list(input())
dp=init(s,t)
for i in range(len(s)):
for j in range(len(t)):
if s[i] == t[j]:
dp[i + 1][j + 1] = dp[i][j]
else:
dp[i + 1][j + 1] = min(dp[i][j] + 1, dp[i][j + 1])
dp[i + 1][j + 1] = min( dp[i + 1][j + 1] ,dp[j+1][i]+1)
print(dp[-1][-1])
这道题目也比较简单,由于是包含关系,并不是相等关系,所以当S多余T是,不需要进行删除操作。
所以这个题目不考虑删除的那个状态转移即可。
def init(s,t):
dp = [[0 for i in range(len(t) + 1)] for j in range(len(s) + 1)]
for i in range(len(s) + 1):
dp[i][0] = 0
for j in range(1,len(t) + 1):
dp[0][j] = 999999
return dp
if __name__ == '__main__':
s = list(input())
t = list(input())
dp=init(s,t)
for i in range(len(s)):
for j in range(len(t)):
if s[i] == t[j]:
dp[i + 1][j + 1] = dp[i][j]
else:
dp[i + 1][j + 1] = min(dp[i][j] + 1, dp[i][j + 1])
print(dp[-1][-1])