51nod1049(计算最大子段和)
题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1049
题意:又是仲文题诶~
思路:暴力会超时,又好像没什么专门的算法,自己yy了一个,算是贪心吧~
暴力的话就是直接枚举所有子段的起始点和终止点咯,但我们仔细想一下可以发现这是没有必要的,我们可以对输入预处理一下,用a[i]存储前i个元素的和,用vis[j]存储第j个字符以前并且以第一个元素开头的子段中最小的和的值,那么a[i]-vis[i]就是以第i个元素结尾的所有子段中最大的和,我们只需要枚举所有结尾元素同时维护一个最大值就可以得到答案了啦~
时间复杂度O(n), n为元素个数;
代码:
1 #include <bits/stdc++.h>
2 #define MAXN 50010
3 #define ll long long
4 using namespace std;
5
6 int main(void){
7 int n;
8 ll a[MAXN], vis[MAXN], ans=0;
9 scanf("%d", &n);
10 for(int i=1; i<=n; i++){
11 ll x;
12 scanf("%lld", &x);
13 a[i]=i?a[i-1]+x:0;
14 }
15 ll MIN=a[0];
16 for(int i=1; i<=n; i++){
17 MIN=min(MIN, a[i-1]);
18 vis[i]=MIN;
19 }
20 for(int i=n; i>0; i--){
21 ans=max(ans, a[i]-vis[i]);
22 }
23 printf("%lld\n", ans);
24 return 0;
25 }
我就是我,颜色不一样的烟火 --- geloutingyu