我试图使用递归来解决最大化子序列和的方法,使得没有三个元素是连续的。
有一种方法可以通过动态编程实现这一点,但我想首先使用递归来构建它。
一些示例输入和输出:
Input:{1, 2, 3}
Output: 5
Input:{100, 1000, 100, 1000, 1}
Output: 2101
Input:{1, 2, 3, 4, 5, 6, 7, 8}
Output: 27
除了第二个{100,1000,100,1000,1}之外,我能够得到大部分正确的结果。
我的解决方案:
int maxSubsequenceSum(vector<int> nums)
{
return helper(nums, nums.size());
}
int helper(vector<int>& nums, int index)
{
if (index <= 0) return 0;
int withoutThird = helper(nums, index - 3) + nums[index - 1] + nums[index - 2];
int withoutSecond = helper(nums, index - 3) + (index - 1 < 0 ? 0 : nums[index - 1]) + (index - 3 < 0 ? 0 : nums[index - 3]);
int withoutFirst = helper(nums, index - 3) + (index - 2 < 0 ? 0 : nums[index - 2]) + (index - 3 < 0 ? 0 : nums[index - 3]);
return max(withoutThird, max(withoutSecond, withoutFirst));
}
单独地,三个 withoutThird , withoutSecond 和 withoutFirst 仅在递归排列时才会给出正确的结果。为什么它会失败,这是一种正确的递归方法吗?
答案 0 :(得分:2)
问题是使用没有三个连续元素来获得最大值。
您正在做的是,一次取3个元素,从中选择两个元素,添加它们等等。
<小时/> 举一个例子: -Input : {A, B, C, D, E, F}
当你的递归从右到左。
假设,考虑,{D,E,F}
(D + E) > (E + F) and (D + E) > (D + F)
您的代码将从最后3个元素中选择{D, E}
。
现在,考虑,{A,B,C}假设,
(B + C) > (A + B) and (B + C) > (A + C)
您的代码将从前3个元素中选择{B, C}
。
总选定元素= {B,C,D,E}。
注意到什么?
您最终添加了四个连续元素。
一个简短的例子:{100,1000,100,1000,1}
2个窗口:[0,1]和[2,4]
从[2,4]中选择{100,1000}
并从[0,1]中选择{100,1000}
添加了四个连续元素
得到:2200,这是你的实际输出。
答案 1 :(得分:1)
withoutSecond
和withoutFirst
有一些错误。为简化起见,我们假设index >= 3
。看看withoutSecond
:
withoutSecond = helper(nums, index - 3) + nums[index - 1] + nums[index - 3]
选择index-1
和index-3
。因此,如果我们在index-4
中选择helper(nums, index - 3)
,则我们无法选择index-5
,但它包含在函数withoutThird
中的helper(nums, index - 3)
中。这会产生更大的结果。
由于条件不允许 3 连续元素。所以我们只需要考虑 2 连续元素来决定是否应该选择另一个元素。
假设f(a, n)
计算大小为a
的数组n
的最大结果。
a[n]
:f(a, n) -> f(a, n-1)
a[n]
&amp;&amp;选择a[n-1]
:f(a, n) -> f(a, n-3) + a[n] + a[n-1]
a[n]
&amp;&amp; 不选择a[n-1]
:f(a, n) -> f(a, n-2) + a[n]
好的,这就是所有3个案例。
有关详细信息,请参阅以下代码
#include <vector>
#include <cstdio>
using namespace std;
// this runs slow
// but you can use memorized search to speed up the process
int helper(vector<int>& nums, int index) {
if (index == 0) return 0;
if (index == 1) return nums[0];
if (index == 2) return nums[0] + nums[1];
int without_last_1 = helper(nums, index-1);
int with_last_1_and_2 = helper(nums, index-3) + nums[index-1] + nums[index-2];
int with_last_1_and_without_last_2 = helper(nums, index-2) + nums[index-1];
return max(without_last_1, max(with_last_1_and_2, with_last_1_and_without_last_2));
}
int maxSubsequenceSum(vector<int> nums) {
return helper(nums, nums.size());
}
int main() {
printf("%d\n", maxSubsequenceSum({1, 2, 3}));
printf("%d\n", maxSubsequenceSum({100, 1000, 100, 1000, 1}));
printf("%d\n", maxSubsequenceSum({1, 2, 3, 4, 5, 6, 7, 8}));
return 0;
}