📅  最后修改于: 2023-12-03 15:10:41.653000             🧑  作者: Mango
给定三个长度为n的数组a、b和c,选择一个长度为n的数组s,s[i]来自a[i]、b[i]、c[i]中的一个,求s的构造方案,使得s中元素之和最大,并且s不能从一个数组中连续取数。
首先,观察这个问题,我们可以想到动态规划。设dp[i][j]表示前i个元素取自第j个数组时的最大和,那么最终的答案就是dp[n][1],dp[n][2],dp[n][3]这三个数中的最大值。但是因为要求不能从同一个数组中连续取数,因此转移方程需要做出改变。对于dp[i][j],将a[j][i]、b[j][i]、c[j][i]三个数按大小排序,然后从大到小枚举它们,并在能够选择的情况下转移。注意这里的“在能够选择的情况下”意味着,如果当前的最大数是a[j][i],那么如果在前面的选择中已经选择了a[j][i-1],就不能在这个位置再选择a[j][i]。
下方为Python实现的代码:
def max_sum(a, b, c):
n = len(a)
dp = [[0] * 4 for _ in range(n+1)] # 多开一列,方便边界情况的处理
for i in range(1, n+1):
nums = sorted([(a[i-1], 1), (b[i-1], 2), (c[i-1], 3)], reverse=True)
for j in range(3):
if nums[j][1] != dp[i-1][0]:
dp[i][nums[j][1]] = dp[i-1][0] + nums[j][0]
break
dp[i][0] = max(dp[i-1])
return max(dp[n])
我们以a = [1, 2, 3], b = [3, 2, 1], c = [2, 3, 1]为例:
max_sum(a, b, c)
输出:
8
本问题解法较为简单,关键在于想到转移方程需要变化,以及如何处理边界情况。如果有同学还有疑问,也可以自行上网查找相关资料学习。