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 }