📅  最后修改于: 2023-12-03 15:37:14.471000             🧑  作者: Mango
有一个长度为$n$的整数数组$A$,我们将它从左到右分成两个数组$L$和$R$,满足$L$和$R$的长度都不为$0$。设$L$数组中所有元素的和为$Lsum$,$R$数组中所有元素的和为$Rsum$,问题是$Lsum = Rsum$的情况下求出$L$和$R$数组中$A$的最长公共连续子序列的长度。
例如,$A={1, 5, 2, 3, 4, 5, 3, 2, 1}$,则$L={1, 5, 2, 3}$,$R={4, 5, 3, 2, 1}$,它们都有相同的和$11$,同时$L$和$R$的最长公共连续子序列是$3$,即$[2,3,4]$。
对于每组测试数据,输出$Lsum = Rsum$时$L$和$R$的最长公共连续子序列的长度。
2
4
2 1 2 1
9
3 4 2 2 4 6 4 2 3
1
2
题目要求在$Lsum = Rsum$的情况下求出$L$和$R$数组中$A$的最长公共连续子序列的长度。
首先我们可以将问题简化为对于$L$和$R$数组的长度$i$和$j$($1\leq i,j\leq n-1$),在满足$Lsum = Rsum$的前提下,求出$A$数组中前$i$个元素和前$j$个元素的最长公共连续子序列的长度。
可以发现上述问题与最长公共子序列问题有异曲同工之妙,我们只需要在求$A_{i}$和$A_{j}$的最长公共子序列时,加入$Lsum = Rsum$的限制即可。
实现上我们可以使用动态规划的方法求解最长公共子序列,然后在填表的时候加入$Lsum = Rsum$的限制即可。
下面是伪码:
for i in range(1, n-1):
for j in range(1, n-1):
# 求A前i个元素和前j个元素的最长公共子序列
lcs = []
# 初始化dp数组
dp = [[0] * (j+1) for k in range(i+1)]
for x in range(1, i+1):
for y in range(1, j+1):
if A[x-1] == A[y-1]:
dp[x][y] = dp[x-1][y-1] + 1
else:
dp[x][y] = max(dp[x][y-1], dp[x-1][y])
# 约束条件
if sum(A[:i]) == sum(A[i:j]):
lcs.append(dp[i][j])
print(max(lcs))