题目链接:Problem - B - Codeforces
大致题意:给定一个序列,你可以将序列划分为若干个连续非空子数组。若子数组内数字和大于0,则该子数字权值为子数组内数字个数;小于0,权值为数字个数的相反数;若等于0,权值为0.现对原序列进行划分,求所有子数组权值之和的最大值。
简易题解:观察到只有区间内数字之和大于0,才能产生贡献,考虑进行动态规划。
f[i] 表示前i位能得到的权值最大值。
求出原序列的前缀和数组p,朴素dp式如下:
for(int i = 1; i <= n; i ++) {
for(int j=0; j<i; j++)
if(p[i] - p[j] > 0) f[i] = max(f[i], f[j] + i - j);
else if(p[i] - p[j] == 0) f[i] = max(f[i], f[j]);
f[i] = max(f[i], f[i - 1] - 1);
}
可以发现,对于每个i,只需要找到所有 满足 $p[j] < p[i]$ 的 j 的f[j] + j 的最大值。
相当于找