D. Running Miles
D. Running Miles
There is a street with sights, with sight number being miles from the beginning of the street. Sight number has beauty . You want to start your morning jog miles and end it miles from the beginning of the street. By the time you run, you will see sights you run by (including sights at and miles from the start). You are interested in the most beautiful sights along your jog, but every mile you run, you get more and more tired.
So choose and , such that there are at least sights you run by, and the sum of beauties of the most beautiful sights minus the distance in miles you have to run is maximized. More formally, choose and , such that is maximum possible, where are the indices of the three maximum elements in range .
Input
The first line contains a single integer () — the number of test cases.
The first line of each test case contains a single integer ().
The second line of each test case contains integers () — beauties of sights miles from the beginning of the street.
It's guaranteed that the sum of all does not exceed .
Output
For each test case output a single integer equal to the maximum value for some running range .
Example
input
8 1 22 299999996
output
8 1 22 299999996
Note
In the first example, we can choose and to be and . So we visit all the sights and the three sights with the maximum beauty are the sights with indices , , and with beauties , , and , respectively. So the total value is .
In the second example, the range can be or , the total value is .
解题思路
比赛的时候写了个假双指针的做法,然后动态规划又没想到怎么做。其实只要想到把公式变一下就能做出来了。
首先根据贪心思想,对于区间,若要让取到最大值,那么其中两个最大元素必然在区间的两个端点,即。否则我们可以通过右移左端点或者左移右端点,使得中的不变,而变小,那么就会变大。
因此,不失一般性,我们假设,,,那么公式就会变成。可以发现的取值仅取决于,的取值仅取决于,因此可以枚举中间元素,然后在中求的最大值,在中求的最大值。前后缀的最大值可以预处理出来。
AC代码如下,时间复杂度为:
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
本文来自博客园,作者:onlyblues,转载请注明原文链接:https://www.cnblogs.com/onlyblues/p/17375929.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效