洛谷-最大子段和-动态规划
题目描述
给出一段序列,选出其中连续且非空的一段使得这段和最大。
输入输出格式
输入格式:输入文件maxsum1.in的第一行是一个正整数N,表示了序列的长度。
第2行包含N个绝对值不大于10000的整数A[i],描述了这段序列。
输出格式:输入文件maxsum1.out仅包括1个整数,为最大的子段和是多少。子段的最小长度为1。
输入输出样例
输入样例#1:
7 2 -4 3 -1 2 -4 3
输出样例#1:
4
说明
【样例说明】2 -4 3 -1 2 -4 3
【数据规模与约定】
对于40%的数据,有N ≤ 2000。
对于100%的数据,有N ≤ 200000。
思路:在这里我只讲一个解决方法,就是动态规划(那些暴力枚举什么的我就不说了)。
我们扫面一个数组,找到一个元素a,存入max中,当我们发现他的下一个元素b和a之和是要比0小,那么我们就认为b是“没有潜力的”,什么意思呢,就是我加上b就变小了,还不如不加,但是我们又不能跳过b去加b后面的元素c,所以遇到这种情况我们就判断这个子段失败,max重新标记为0。
如果加上下一个元素b大于0,就可以判断我们目前全局的答案ans是比这个和要大还是小,如果大更新一下ans的值,否则就不变。
最后输出ans就得了。
代码如下:
1 #include <stdio.h> 2 int COMPAREMAX(int a,int b) 3 { 4 return a>b?a:b; 5 } 6 int main() 7 { 8 int a[200002]; 9 int n,i; 10 scanf("%d",&n); 11 for(i=0;i<n;i++) 12 { 13 scanf("%d",&a[i]); 14 } 15 int max=0,ans=0; 16 for(i=0;i<n;i++) 17 { 18 if(max+a[i]<0) 19 { 20 max=0; 21 } 22 else 23 { 24 ans=COMPAREMAX(ans,max+=a[i]); 25 } 26 } 27 if(ans==0)//有负数 28 { 29 ans=a[0]; 30 for(i=1;i<n;i++) 31 { 32 if(a[i]>ans) 33 { 34 ans=a[i]; 35 } 36 } 37 } 38 printf("%d\n",ans); 39 return 0; 40 }
我不怕千万人阻挡,只怕自己投降…