HDU - 1003 MAX SUM(dp)

题目:

题意: 让求给出的序列中连续的一个子序列的和的最大值,以及这个子序列的起点和终点。

思路:dp求当前位置的最大值,dp[i] = max(dp[i-1], a[i]);最大值的位置就是终点,既然知道了和的大小,那么,只要找出那个区间的和是该值就可以了,这里可以用一个前缀和数组来求开始的位置。

ps:dp还是得多思考、多练啊!!

代码:

 1 #include <iostream>
 2 #include <queue>
 3 #include <cstdio>
 4 #include <algorithm>
 5 #include <cmath>
 6 #include <cstring>
 7 #include <queue>
 8 #include <map>
 9 #include <vector>
10 #define INF 0x3f3f3f3f
11 #define FRE() freopen("in.txt","r",stdin)
12 
13 using namespace std;
14 typedef long long ll;
15 const int maxn = 1e5+10;
16 int a[maxn],dp[maxn],sum[maxn];
17 int main()
18 {
19     int T,n,cnt = 1;
20     scanf("%d",&T);
21     while(T--)
22     {
23         memset(a,0,sizeof(a));
24         memset(dp,0,sizeof(dp));
25         memset(sum,0,sizeof(sum));
26         scanf("%d",&n);
27         for(int i = 1; i<=n; i++)
28         {
29             scanf("%d",&a[i]);
30             sum[i] = sum[i-1]+a[i];
31         }
32         int st = 0,en = 0,mmax = -INF,f = 1;
33         for(int i = 1; i<=n; i++)
34         {
35             dp[i] = max(dp[i-1]+a[i],a[i]);
36             if(dp[i]>mmax)
37             {
38                 mmax = dp[i];
39                 en = i;
40             }
41         }
42         for(int i = 1; i<=en; i++)
43         {
44             if(sum[en]-sum[i-1] == mmax)
45             {
46                 st = i;
47                 break;
48             }
49         }
50         if(cnt!=1)printf("\n");
51         printf("Case %d:\n",cnt++);
52         printf("%d %d %d\n",mmax,st,en);
53     }
54     return 0;
55 }
56 
57 /*
58 样例输入:
59 2
60 5 6 -1 5 4 -7
61 7 0 6 -1 1 -6 7 -5
62 样例输出:
63 Case 1:
64 14 1 4
65 
66 Case 2:
67 7 1 6
68 */
View Code

 

posted @ 2018-10-02 19:45  sykline  阅读(174)  评论(0编辑  收藏  举报