poj2479

最近一阶段写了dp的专题,这是第一题。

题目大意:给定一段数,要求你求出两段和最大的。。

思路:直接两遍的最大和子序列,前面一遍,后面一遍。。然后加起来。。

 1 /*
 2   Author:yzcstc
 3   Time:2013.2.26
 4   State:AC
 5 */
 6 #include <iostream>
 7 #include <cstdlib>
 8 #include <cstdio>
 9 #include <cmath>
10 #include <cstring>
11 #include <string>
12 #include <algorithm>
13 using namespace std;
14 const int minn = -500000001;
15 int T , n , a[100005], lsum[3][100005], rsum[3][100005] , ans;
16 
17 void dp(){
18       ans = minn;
19       scanf("%d",&n);
20       lsum[0][0] = lsum[1][0] = minn;
21       rsum[0][n + 1] = rsum[1][n + 1] = minn;
22       for (int i = 1; i <= n; ++i)
23         {
24             scanf("%d",&a[i]);
25             lsum[0][i] = max(lsum[0][i - 1] + a[i] , a[i]);
26             lsum[1][i] = max(lsum[1][i - 1] , lsum[0][i - 1]);
27         }
28 
29       for (int i = n; i >= 1; --i)
30          {
31 
32             rsum[0][i] = max(rsum[0][i + 1] + a[i] , a[i]);
33             rsum[1][i] = max(rsum[1][i + 1] , rsum[0][i + 1]);
34          }
35       for (int i = 2; i <= n; ++i)
36             ans = max( ans , 
37             max(lsum[0][i - 1], lsum[1][i - 1]) + max( rsum[0][i] , rsum[1][i]));
38 }
39 
40 int main(){
41       freopen("poj2479.in","r",stdin);
42       freopen("poj2479.out","w",stdout);
43       scanf("%d",&T);
44       for (int i = 1 ; i <= T; ++i)
45         {
46              dp();
47              printf("%d\n",ans);
48         }
49       fclose(stdin); fclose(stdout);
50 }

 

posted on 2013-03-23 18:56  yzcstc  阅读(297)  评论(0编辑  收藏  举报