C. Functions again
题意
给定有 n 个元素的数组 a 以及公式 f(l,r)=Σr−1i=l∣a[i]−a[i+1]∣⋅(−1)i−l 。求在 1≤l<r≤n 的情况下,最大的 f(l,r) 。
解题思路
此题可以视作是前缀和的一个变体。
令 sub[i]=∣a[i]−a[i+1]∣ ,将数组 a 预处理成长为 n-1 的数组 sub 。
此时对该数组 sub 做前缀和计算,唯一的不同在于计算时需对 sub 做 ×(−1)i 处理。记录 [1, i] 中的最小值与最大值做差获取 max(f(l,r)) 。
需要注意:由于公式 f(l,r) 的第一项一定为 +sub[i] ,故 [1, i] 中的最小值只能去 −sub[i] 项。
上述已经计算了一半的可能性,仍需要考虑,每一项都可能被作为负项,故再计算对 sub 做 ×(−1)i+1 的情况。
代码
#include<bits/stdc++.h>
using namespace std;
const long long inf = 2e9 + 10;
int n, a[100010];
long long sub[100010], pre[100010];
long long solve(int flg)
{
long long ans = 0, mx = -inf, mn = 0;
for(int i=1;i<n;i++)
{
if(i%2 == flg) pre[i] = pre[i-1] + sub[i];
else pre[i] = pre[i-1] - sub[i];
}
for(int i=1;i<n;i++)
{
if(i%2 != flg) mn = min(mn, pre[i]);
mx = max(mx, pre[i]);
ans = max(ans, mx - mn);
}
return ans;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<n;i++)
sub[i] = abs(a[i] - a[i+1]);
long long ans = max(solve(1), solve(0));
printf("%I64d\n", ans);
}