CF1826D
CF1826D
链接:
题目大意:
给你一个数组,让你选择一个区间\([l, r]\)设选中的区间为\(b\),\(b_{i_1} + b_{i_2} + b_{i_3}\)为区间内前三大的值,你需要选择一个区间使得\(b_{i_1} + b_{i_2} + b_{i_3} - (r - l)\)值最大,输出最大值
思路:
- 我们发现三个数一定是\(b_l,b_r\)还有区间内一个数,因为,如果左右两个端点不是最大的数,那么我们缩小区间不是更优吗
- 我们考虑分项 \(b_l + l\) 一项, \(b_r - r\) 一项然后中间值一项,这样我们通过前缀后缀预处理,再枚举中间项就能得出答案
代码:
void solve(){
int n;
cin >> n;
int a[n + 1];
for(int i = 1;i<=n;i++) cin >> a[i];
int pre[n + 2],suf[n + 2];
memset(pre,0,sizeof pre);
memset(suf,-0x3f,sizeof suf);
int res = 0;
for(int i = 1;i<=n;i++) pre[i] = max(pre[i - 1],a[i] + i);
for(int i = n;i>=1;i--) suf[i] = max(suf[i + 1],a[i] - i);
for(int i = 2;i < n;i++) res=max(res,pre[i - 1] + suf[i + 1] + a[i]);
cout << res << endl;
}
时间复杂度
O(n)