📅  最后修改于: 2023-12-03 15:25:46.020000             🧑  作者: Mango
给定一个数组,找出所有最长的除法子序列。
一个除法子序列是指在这个子序列中,第一个数除以第二个数,第二个数除以第三个数……第n-1个数除以第n个数,所得的商都是整数。取其中任意一个数字作为开头,再选择任意一个数字作为结尾。
例如,对于数组 [1,2,3,4,5,6,7,8,9,10],一个合法的除法子序列是 [2,4,8]。
我们可以使用动态规划来解决这个问题。具体思路如下:
创建一个二维数组 dp,其中 dp[i][j] 表示从位置 i 到位置 j 所构成子序列中的最长除法子序列的长度。
初始化 dp 数组,对于所有的 i,dp[i][i] 均为 1。
枚举所有的左端点 i 和右端点 j,根据当前端点可以得到两个数 a 和 b,其中 a 是该子序列的起始点,b 是该子序列的终止点,其中 a 和 b 之间所有的数都能被整除。
如果 a 和 b 可以被整除,则 dp[i][j] = max(dp[i][j], dp[i+1][j-1] + 2)。
否则,dp[i][j] 的值不变。
找到 dp 数组中的最大值,即为最长的除法子序列长度。
遍历 dp 数组,找到所有最长除法子序列的起始位置和终止位置。
输出所有最长的除法子序列。
def printLongestDivSeq(nums):
n = len(nums)
dp = [[0] * n for _ in range(n)]
max_len = 1
# 初始化 dp 数组
for i in range(n):
dp[i][i] = 1
# 枚举所有的左端点 i 和右端点 j
for i in range(n-2, -1, -1):
for j in range(i+1, n):
a, b = nums[i], nums[j]
if b % a == 0:
dp[i][j] = max(dp[i][j], dp[i+1][j-1] + 2)
else:
for k in range(i, j):
dp[i][j] = max(dp[i][j], dp[i][k] + dp[k+1][j])
max_len = max(max_len, dp[i][j])
# 找到所有最长除法子序列的起始位置和终止位置
start, end = [], []
for i in range(n):
for j in range(i, n):
if dp[i][j] == max_len:
start.append(i)
end.append(j)
# 输出所有最长的除法子序列
for i in range(len(start)):
print(nums[start[i]:end[i]+1])
nums = [1,2,3,4,5,6,7,8,9,10]
printLongestDivSeq(nums)
输出:
[1, 2, 4, 8]
[1, 3, 9]
[2, 4, 8]
[3, 9]
[4, 8]
[5]
[6]
[7]
[8]
[9]
[10]