目录
1911. 最大子序列交替和
题目描述:
一个下标从 0 开始的数组的 交替和 定义为 偶数 下标处元素之 和 减去 奇数 下标处元素之 和 。
- 比方说,数组
[4,2,5,3]
的交替和为(4 + 5) - (2 + 3) = 4
。
给你一个数组 nums
,请你返回 nums
中任意子序列的 最大交替和 (子序列的下标 重新 从 0 开始编号)。
一个数组的 子序列 是从原数组中删除一些元素后(也可能一个也不删除)剩余元素不改变顺序组成的数组。比方说,[2,7,4]
是 [4,2,3,7,2,1,4]
的一个子序列(加粗元素),但是 [2,4,2]
不是。
示例 1:
输入:nums = [4,2,5,3] 输出:7 解释:最优子序列为 [4,2,5] ,交替和为 (4 + 5) - 2 = 7 。
示例 2:
输入:nums = [5,6,7,8] 输出:8 解释:最优子序列为 [8] ,交替和为 8 。
示例 3:
输入:nums = [6,2,1,2,4,5] 输出:10 解释:最优子序列为 [6,1,5] ,交替和为 (6 + 5) - 1 = 10 。
实现代码与解析:
贪心
class Solution {
public:
long long maxAlternatingSum(vector<int>& nums) {
long long res = 0;
vector<int> f(nums.size(), 0);
if (nums[0] > 0) res += nums[0];
for (int i = 1; i < nums.size(); i++)
{
if (nums[i] > nums[i - 1]) res += nums[i] - nums[i - 1];
}
return res;
}
};
原理思路:
我们分析题目,发现他说偶数下标减去奇数下标,而且他这个奇数和偶数指的是结果数组中,所以我们把结果数组中的两个元素看成一对,那不就成了买卖股票Ⅱ那道题了么,偶数是卖出入,奇数是买入,求赚最多的利润。这样这题就很简单了,可以看看之前的这篇文章:Leetcode:121. 买卖股票的最佳时机、122. 买卖股票的最佳时机 II、123. 买卖股票的最佳时机 III、188. 买卖股票的最佳时机 IV(C++)_Cosmoshhhyyy的博客-CSDN博客
原理和那道题一样,只要赚钱就卖出,在这里就是只要前一天比今天小,我们res就加上这个差值,不过这里只有一点不同,就是这题数组前面要加一个0,把第一天单独计算一下即可。
当然,很明显和买卖股票一样,也是可以通过动态规划来解决的。
动态规划
class Solution {
public:
long long maxAlternatingSum(vector<int>& nums) {
long long res = 0;
vector<vector<long long int>> f(nums.size(), vector<long long>(2, 0)); // 0 选取了偶数的状态, 1 选取了奇数的状态
f[0][0] = nums[0], f[0][1] = 0; //显然第一个数
for (int i = 1; i < nums.size(); i++)
{
f[i][0] = max(f[i - 1][0], f[i - 1][1] + nums[i]); // 选取了偶数的状态
f[i][1] = max(f[i - 1][1], f[i - 1][0] - nums[i]); // 选取了奇数的状态
}
return max(f[nums.size() - 1][0], f[nums.size() - 1][1]);
}
};
原理思路:
对于写过买卖股票全系列题目来说,就很简单的,建议去学习一下。dp[i][2] 这里表示对第 i 个数进行选择或不选择,第二维 0 选取了偶数的状态, 1 选取了奇数的状态的最大值。当然你定义bool或者任意数也可以。其他就没什么了。