您的位置:首页 > 其它

poj 2479 Maximum sum(求最大子段和的延伸)

2014-09-12 10:40 459 查看
<p>//题目:<a target=_blank href="http://poj.org/problem?id=2479">http://poj.org/problem?id=2479</a></p><p></p><p style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px; font-family: Arial; font-size: 14px; line-height: 26px;">//题意:</p><p style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px; font-family: Arial; font-size: 14px; line-height: 26px;">//   <span style="font-family: SimSun;">    题目的大概意思是把数组分成不交两段,分别求出两段的最大子段和s1和s2,然后求出最大的s1+s2。</span></p><p style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px; font-size: 14px; line-height: 26px;"><span style="font-family: SimSun;">//这种问题往往感觉像字符串问题,所以记下来,经常会用</span></p>
#include <iostream>#include <iomanip>#include <fstream>#include <sstream>#include <algorithm>#include <string>#include <set>#include <Map>#include <utility>#include <queue>#include <stack>#include <list>#include <vector>#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>using namespace std;const int maxn = 50005;int left1[maxn];        //left1和right1分别记从哪个方向来的最大数int right1[maxn];int a[maxn];int main(){int t, n;scanf("%d", &t);while (t--){scanf("%d", &n);for (int i = 1; i <= n; i++){scanf("%d", &a[i]);}left1[1] = a[1];for (int i = 2; i <= n; i++)        //left从左往右加的时候,一旦前面的和为负,后边就另起炉灶记最大数{if (left1[i-1] > 0)left1[i] = left1[i-1] + a[i];elseleft1[i] = a[i];}for (int i = 2; i <= n; i++)   //最大之和肯定是第i个或者第i-1个left1[i] = max(left1[i], left1[i-1]);right1= a;for (int i =n-1;i>=1;i--){if(right1[i+1] > 0){right1[i] = right1[i+1] +a[i];}elseright1[i] = a[i];}for(int i =n-1;i>=1;i--)right1[i] = max(right1[i],right1[i+1]);int ans = left1[1] + right1[2];for (int i = 2; i < n; i++){ans = max(left1[i]+right1[i+1], ans);}printf("%d\n", ans);}return 0;}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: