题目链接: 点我跳转
题目大意:给出一段序列,选出其中连续且非空的一段使得这段和最大。
题目分析:刚开始想到想到尺取法去了,显然尺取法不能取出最大的一段,不适合此类题型。既然是一段的和,很自然地应该想到前缀和,然后只要求出
a
i
−
a
j
(
i
>
j
)
a_i-a_j (i>j)
ai−aj(i>j)的最大值就OK了。我觉得这个可以算动规,从右向左遍历,不断更新当前右侧的最大值,每次计算当前值和最大值的差即可。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define INF 0x7fffffff
int in[200000+5];
int main(){
int n;cin>>n;
for(int i=1;i<=n;i++)
scanf("%d",&in[i]),in[i+1] += in[i];//前缀和
int mx(in[n]),ans(INF+1);
for(int i=n-1;i>=0;i--){
ans = max(ans,mx - in[i]);//更新与最大值的差
if(i!=0 && in[i] > mx)mx = in[i];//更新最大值
}
cout<<ans;
return 0;
}