D. YET ANOTHER YET ANOTHER TASK【枚举的转化+区间最大连续子段和】

http://www.yyycode.cn/index.php/2020/05/30/d-yet-another-yet-another-task%e3%80%90%e6%9e%9a%e4%b8%be%e7%9a%84%e8%bd%ac%e5%8c%96%e5%8c%ba%e9%97%b4%e6%9c%80%e5%a4%a7%e8%bf%9e%e7%bb%ad%e5%ad%90%e6%ae%b5%e5%92%8c%e3%80%91/


Alice and Bob are playing yet another card game. This time the rules are the following. There are nn cards lying in a row in front of them. The ii-th card has value aiai.

First, Alice chooses a non-empty consecutive segment of cards [l;r][l;r] (l≤rl≤r). After that Bob removes a single card jj from that segment (l≤j≤r)(l≤j≤r). The score of the game is the total value of the remaining cards on the segment (al+al+1+⋯+aj−1+aj+1+⋯+ar−1+ar)(al+al+1+⋯+aj−1+aj+1+⋯+ar−1+ar). In particular, if Alice chooses a segment with just one element, then the score after Bob removes the only card is 00.

Alice wants to make the score as big as possible. Bob takes such a card that the score is as small as possible.

What segment should Alice choose so that the score is maximum possible? Output the maximum score.Input

The first line contains a single integer nn (1≤n≤1051≤n≤105) — the number of cards.

The second line contains nn integers a1,a2,…,ana1,a2,…,an (−30≤ai≤30−30≤ai≤30) — the values on the cards.Output

Print a single integer — the final score of the game.ExamplesinputCopy

5
5 -2 10 -1 4

outputCopy

6

inputCopy

扫描二维码关注公众号,回复: 11339477 查看本文章
8
5 2 5 3 -30 -30 6 9

outputCopy

10

inputCopy

3
-10 6 -15

outputCopy

0

Note

In the first example Alice chooses a segment [1;5][1;5] — the entire row of cards. Bob removes card 33 with the value 1010 from the segment. Thus, the final score is 5+(−2)+(−1)+4=65+(−2)+(−1)+4=6.

In the second example Alice chooses a segment [1;4][1;4], so that Bob removes either card 11 or 33 with the value 55, making the answer 5+2+3=105+2+3=10.

In the third example Alice can choose any of the segments of length 11: [1;1][1;1], [2;2][2;2] or [3;3][3;3]. Bob removes the only card, so the score is 00. If Alice chooses some other segment then the answer will be less than 00.


题意: 要求找到“区间和-区间最大值”的最大值

思路:如果通过枚举区间和去思考十分难思考。

思维转化一下:我们通过枚举区间最大值求思考。

对一段区间,如果全都是负数,那么区间和 -区间最大值的最大值一定是0;

我们枚举区间最大值,当累加的连续子段和的下一个a[j]>i的时候,我们把sum重置=0;并且开始新的sum累加。在sum<0的情况下,我们也重置sum=0(因为sum最小为0并且这段sum<0对以后的答案没有贡献。可以回想最大连续子段和的累加);然后我们不断更新最大值即可

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1e5+10;
typedef long long LL;
LL a[maxn];
int main(void)
{
	LL n;cin>>n;
	for(LL i=1;i<=n;i++) cin>>a[i];
	//枚举区间最大值
	LL ans=-0x3f3f3f3f; 
	//区间最大值要从非负数开始枚举。
	//因为如果区间最大值是负数,那么最大子段和的必然是0(只取一个)
	//不会有下面的sum的变化,可以用特判解决 
	for(LL i=0;i<=30;i++)
	{
		LL sum=0;//全是负数最差的情况sum=0;因为要减去唯一的负数 
		//枚举连续最大子段和 
		for(LL j=1;j<=n;j++)
		{
			if(a[j]>i)//不符合区间内<=区间最大值的假设 
			{
				sum=0;continue;
			}
			sum+=a[j];
			if(sum<0) sum=0;
			ans=max(ans,sum-i);		
		}
		
	}
	cout<<ans<<endl;
return 0;
}

猜你喜欢

转载自blog.csdn.net/zstuyyyyccccbbbb/article/details/106447314