题意
一个人从起点000出发。
他现在如果在iii,那么如果跳到jjj,那么获得的价值为(j−i)∗aj(j-i)*a_j(j−i)∗aj。
求刚好落到终点nnn的最大可获得的价值。
思路
刚开始看到就想到O(n2)的dpO(n^2)的dpO(n2)的dp,结果看了下数据发现只能拿606060分,正解是斜率优化(当然我这么菜怎么可能打 )。
可以用贪心,我们每次从iii跳都直接跳到后面最大的aja_jaj。
证明:
设后面最大的aaa为aja_jaj,在起点和jjj中有一个iii。
那么从起点xxx出发到iii再到jjj的价值就是ai∗(i−x)+aj∗(j−i)a_i*(i-x)+a_j*(j-i)ai∗(i−x)+aj∗(j−i);
从起点xxx直接到jjj的价值就是aj∗(j−x)a_j*(j-x)aj∗(j−x)
显然第二个优于第一个。
代码
#include<cstdio>
#include<algorithm>
int n, ans;
int a[100001], maxa[100001];
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);
for (int i = n; i >= 1; i--)
maxa[i] = std::max(maxa[i + 1], a[i]);
int next = 0;
for (int i = 1; i <= n; i++)
if (a[i] == maxa[next + 1]) {
ans += a[i] * (i - next);
next = i;
}
printf("%d", ans);
}