Max Sum HDU - 1003

原题链接

考察:线性dp

思路:

       f[i]定义为以i结尾的连续子序列的最大值,划分集合分为a[i]做起点,或者从前面的最大值连续到a[i],状态转移方程是f[i] = max(f[i-1]+a[i],a[i]).

       本题最难的点在找起点和终点(对本蒟蒻而言)....下面的测试数据可以测出代码是不是"短视"了

       我们求的ans在前段被更新为较大的值,但真正的ans是从10处开始累加,起始不会>ans,所以需要一个变量记录每一个新开始子序列的start值.

1
15 549 -945 -581 -450 627 744 -642 -964 -788 767 962 602 832 -477 916
 1 #include <iostream>
 2 #include <cstring>
 3 using namespace std;
 4 const int N = 100010,INF = -2147483648;
 5 int a[N],n,f[N];
 6 int main()
 7 {
 8     int T,kcase = 0;
 9     scanf("%d",&T);
10     while(T--)
11     {
12         scanf("%d",&n);
13         if(kcase) printf("\n");
14         for(int i=1;i<=n;i++) scanf("%d",&a[i]);
15         int st =1,start = 1,ed =1,ans = a[1];
16         for(int i=1;i<=n;i++)
17         {
18             f[i] = a[i];
19             if(f[i-1]+a[i]>=f[i])
20             {//连续的序列,ed延长 
21                 f[i] = f[i-1]+a[i]; 
22                 if(f[i]>ans) ans = f[i],ed = i,st = start;
23                 continue;
24             }//新开的序列,st 重新赋值. 
25             else{
26                 start = i;
27                 if(f[i]>ans) ans = f[i],st = i,ed = i;
28             }
29         }
30         printf("Case %d:\n%d %d %d\n",++kcase,ans,st,ed);
31     }
32     return 0;
33 }

 

posted @ 2021-03-12 17:04  acmloser  阅读(42)  评论(0编辑  收藏  举报