D. Running Miles

D. Running Miles

There is a street with n sights, with sight number i being i miles from the beginning of the street. Sight number i has beauty bi. You want to start your morning jog l miles and end it r miles from the beginning of the street. By the time you run, you will see sights you run by (including sights at l and r miles from the start). You are interested in the 3 most beautiful sights along your jog, but every mile you run, you get more and more tired.

So choose l and r, such that there are at least 3 sights you run by, and the sum of beauties of the 3 most beautiful sights minus the distance in miles you have to run is maximized. More formally, choose l and r, such that bi1+bi2+bi3(rl) is maximum possible, where i1,i2,i3 are the indices of the three maximum elements in range [l,r].

Input

The first line contains a single integer t (1t105) — the number of test cases.

The first line of each test case contains a single integer n (3n105).

The second line of each test case contains n integers bi (1bi108) — beauties of sights i miles from the beginning of the street.

It's guaranteed that the sum of all n does not exceed 105.

Output

For each test case output a single integer equal to the maximum value bi1+bi2+bi3(rl) for some running range [l,r].

Example

input

8
1
22
299999996

output

8
1
22
299999996

Note

In the first example, we can choose l and r to be 1 and 5. So we visit all the sights and the three sights with the maximum beauty are the sights with indices 1, 3, and 5 with beauties 5, 4, and 3, respectively. So the total value is 5+4+3(51)=8.

In the second example, the range [l,r] can be [1,3] or [2,4], the total value is 1+1+1(31)=1.

 

解题思路

  比赛的时候写了个假双指针的做法,然后动态规划又没想到怎么做。其实只要想到把公式变一下就能做出来了。

  首先根据贪心思想,对于区间[l,r],若要让bi1+bi2+bi3(rl)取到最大值,那么其中两个最大元素必然在区间的两个端点,即al,ar{bi1,bi2,bi3}。否则我们可以通过右移左端点l或者左移右端点r,使得[l,r]中的bi1,bi2,bi3不变,而rl变小,那么bi1+bi2+bi3(rl)就会变大。

  因此,不失一般性,我们假设i1=li3=ri2=i(l,r),那么公式就会变成bl+bi+br(rl)=ai+(al+l)+(arr)。可以发现al+l的取值仅取决于larr的取值仅取决于r,因此可以枚举中间元素ai,然后在l[1,i1]中求al+l的最大值,在r[i+1,n]中求arr的最大值。前后缀的最大值可以预处理出来。

  AC代码如下,时间复杂度为O(n)

复制代码
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int N = 1e5 + 10, INF = 0x3f3f3f3f;
 5 
 6 int a[N];
 7 int l[N], r[N];
 8 
 9 void solve() {
10     int n;
11     scanf("%d", &n);
12     l[0] = r[n + 1] = -INF;
13     for (int i = 1; i <= n; i++) {
14         scanf("%d", a + i);
15         l[i] = max(l[i - 1], a[i] + i);
16     }
17     for (int i = n; i; i--) {
18         r[i] = max(r[i + 1], a[i] - i);
19     }
20     int ret = 0;
21     for (int i = 1; i <= n; i++) {
22         ret = max(ret, a[i] + l[i - 1] + r[i + 1]);
23     }
24     printf("%d\n", ret);
25 }
26 
27 int main() {
28     int t;
29     scanf("%d", &t);
30     while (t--) {
31         solve();
32     }
33     
34     return 0;
35 }
复制代码

 

参考资料

  Codeforces Round #870 (Div. 2) Editorial:https://codeforces.com/blog/entry/115892

posted @   onlyblues  阅读(168)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
Web Analytics
点击右上角即可分享
微信分享提示