📅  最后修改于: 2023-12-03 15:12:46.469000             🧑  作者: Mango
这是一个计算量较大的题目,需要使用动态规划算法。
给定一个长度为n的数组a和一个长度为m的数组b,从数组a和数组b中各选取一个连续子序列,使得这两个子序列的长度之和最小。
定义dp[i][j]表示以a[i]和b[j]结尾的子序列的长度之和最小值。
状态转移方程为:
dp[i][j] = min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1, if a[i] == b[j]
dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + 1, if a[i] != b[j]
其中,当a[i]和b[j]相等时,dp[i][j]可以从dp[i-1][j]、dp[i][j-1]和dp[i-1][j-1]三种状态转移而来;当a[i]和b[j]不相等时,dp[i][j]只能从dp[i-1][j]和dp[i][j-1]两种状态转移而来。
最终答案为:
ans = min(dp[i][j]), 1 ≤ i ≤ n, 1 ≤ j ≤ m
def min_length(a, b):
n = len(a)
m = len(b)
dp = [[float('inf')] * (m+1) for _ in range(n+1)]
for i in range(1, n+1):
for j in range(1, m+1):
if a[i-1] == b[j-1]:
dp[i][j] = min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1
else:
dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + 1
ans = float('inf')
for i in range(1, n+1):
for j in range(1, m+1):
ans = min(ans, dp[i][j])
return ans
# 门|门 IT 2006 |第 42 题
这是一个计算量较大的题目,需要使用动态规划算法。
## 题目描述
给定一个长度为n的数组a和一个长度为m的数组b,从数组a和数组b中各选取一个连续子序列,使得这两个子序列的长度之和最小。
## 动态规划算法
定义dp[i][j]表示以a[i]和b[j]结尾的子序列的长度之和最小值。
状态转移方程为:
dp[i][j] = min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1, if a[i] == b[j] dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + 1, if a[i] != b[j]
其中,当a[i]和b[j]相等时,dp[i][j]可以从dp[i-1][j]、dp[i][j-1]和dp[i-1][j-1]三种状态转移而来;当a[i]和b[j]不相等时,dp[i][j]只能从dp[i-1][j]和dp[i][j-1]两种状态转移而来。
最终答案为:
ans = min(dp[i][j]), 1 ≤ i ≤ n, 1 ≤ j ≤ m
## 完整代码
```python
def min_length(a, b):
n = len(a)
m = len(b)
dp = [[float('inf')] * (m+1) for _ in range(n+1)]
for i in range(1, n+1):
for j in range(1, m+1):
if a[i-1] == b[j-1]:
dp[i][j] = min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1
else:
dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + 1
ans = float('inf')
for i in range(1, n+1):
for j in range(1, m+1):
ans = min(ans, dp[i][j])
return ans