📌  相关文章
📜  来自三个数组的最大和,不允许从该数组连续拾取元素(1)

📅  最后修改于: 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
总结

本问题解法较为简单,关键在于想到转移方程需要变化,以及如何处理边界情况。如果有同学还有疑问,也可以自行上网查找相关资料学习。