POJ 2479

求最长子段和问题,但是是求两段的子段和。

也就是对每个i来说,求出[0~i-1]的最大子段和以及[i~n-1]的最大子段和,再相加起来。

求最大的一个就行了。

[0~i-1]的最大子段和从左向右扫描,[i~n-1]从右向左扫描即可。

时间复杂度为O(n).

在输入的时候,开始用的是iostream,结果超时,要用scanf。497ms...


#include <cstdio>
#include 
<algorithm>
using namespace std;

int v[50001];
int left[50001];
int right[50001];
    
void solve()
{
    
int casessize;
    scanf(
"%d",&casessize);
    
while(casessize--){
        
int size;

        scanf(
"%d",&size);

        
for(int i=0;i<size;++i)
           scanf(
"%d",&v[i]);
 
    
// 此时left[i] 为包含i最大子段和
    left[0= v[0];
   
    
for(int i=1;i<size;++i){
        
if(left[i-1]<0)
           left[i] 
= v[i];
        
else
            left[i] 
= left[i-1]+v[i];
    }

    
// 此时left[i] 为i左边最大子段和
    for(int i=1;i<size;++i)
       left[i] 
= max(left[i],left[i-1]);

    right[size
-1= v[size-1];
    
for(int j=size-2;j>=0;j--){
        
if(right[j+1]<0)
            right[j] 
= v[j];
        
else
            right[j] 
= right[j+1]+v[j];
    }

    
for(int i=size-2;i>=0;i--)
        right[i] 
= max(right[i+1],right[i]);

    
int res = INT_MIN;
    
for(int i=1;i<size;++i){
        res 
= max(res,left[i-1]+right[i]);
    }
        printf(
"%d\n",res);
    }
}

int main()
{
    solve();
    
return 0;
}

 

posted on 2009-06-03 11:15 YZY 阅读(2125) 评论(1)  编辑 收藏 引用 所属分类: AlgorithmPOJ


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


导航

<2009年6月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

统计

常用链接

留言簿(2)

随笔分类

随笔档案

搜索

积分与排名

最新评论

阅读排行榜