HDU 1231 最大连续子序列:水dp
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1231
题意:
给你一个整数序列,求连续子序列元素之和最大,并输出该序列的首尾元素(若不唯一,输出首坐标最小的;首坐标相同输出尾坐标最小的)。
题解:
O(N)做法。
定义sum为当前坐标i之前某一段元素[x,i-1]之和。
三种情况:
(1)sum > 0:说明之前的和对答案有贡献,更新sum += a[i],tail = a。
(2)sum < 0:前面的答案是拖后腿的。。。还不如从a[i]重新开始算,sum = a[i],head = a,tail = a。
(3)sum = 0:可要可不要。但答案要求首坐标最小,就要了,同sum > 0的情况。
如果某次sum > ans,则更新:ans = sum, lef = head, rig = tail
AC Code:
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #define INF 10000000 5 6 using namespace std; 7 8 int n; 9 int a; 10 int ans; 11 int lef,rig; 12 int start,over; 13 14 int main() 15 { 16 while(cin>>n) 17 { 18 if(n==0) break; 19 int head; 20 int tail=-1; 21 int sum=-INF; 22 ans=-INF; 23 for(int i=0;i<n;i++) 24 { 25 cin>>a; 26 if(i==0) start=a; 27 if(i==n-1) over=a; 28 if(sum>=0) 29 { 30 sum+=a; 31 tail=a; 32 } 33 else 34 { 35 sum=a; 36 head=a; 37 tail=a; 38 } 39 if(sum>ans) 40 { 41 ans=sum; 42 lef=head; 43 rig=tail; 44 } 45 } 46 if(ans>=0) cout<<ans<<" "<<lef<<" "<<rig<<endl; 47 else cout<<"0 "<<start<<" "<<over<<endl; 48 } 49 }