POJ 2479 不相交最大子段和

题目意思还是很好理解的,在一个数列中,找出不相交的两个子串使得其和最大。

解题思路:

  对于每个i来说,求出[0 ~ i - 1] 的最大子段和以及[i ~ n - 1]的最大子段和,在加起来,求最大的一个就行了。

  [0 ~ i - 1]的最大子段和从左向右扫描,[i ~ n - 1] 的最大子段和从右向左扫描即可。时间复杂度为 O(n)

source code:

//#pragma comment(linker, "/STACK:16777216") //for c++ Compiler
#include <stdio.h>
#include <iostream>
#include <cstring>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <algorithm>
#define ll long long
#define Max(a,b) (((a) > (b)) ? (a) : (b))
#define Min(a,b) (((a) < (b)) ? (a) : (b))
#define Abs(x) (((x) > 0) ? (x) : (-(x)))

const int INF  = 0x3f3f3f3f;
int a[50001], left[50001], right[50001];
int main(){
    int i, j, t, k, n, m;
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        for(i = 0; i < n; ++i)  scanf("%d",&a[i]);
        left[0] = a[0];
        for(i = 1; i < n; ++i){
            if(left[i - 1] < 0)
                left[i] = a[i];
            else
                left[i] = left[i - 1] + a[i];
        }
        for(i = 1; i < n; ++i){
            left[i] = Max(left[i - 1], left[i]);    //Max segment sum
        }
        right[n - 1] = a[n - 1];
        for(i = n - 2; i >= 0; --i){
            if(right[i + 1] < 0)
                right[i] = a[i];
            else
                right[i] = right[i + 1] + a[i];
        }
        for(i = n - 2; i > 0; --i){
            right[i] = Max(right[i + 1], right[i]); //Max segment sum
        }
        int MAX = -INF;
        for(i = 1; i < n; ++i){
            MAX = Max(MAX, left[i - 1] + right[i]);
        }
        printf("%d\n",MAX);
    }
    return 0;
}
时间: 2024-10-02 01:53:23

POJ 2479 不相交最大子段和的相关文章

51nod 1052最大M子段和 &amp; poj 2479最大两子段和

最大子段和经典问题的扩展. 题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1052 N个整数组成的序列a[1],a[2],a[3],…,a[n],将这N个数划分为互不相交的M个子段,并且这M个子段的和是最大的.如果M >= N个数中正数的个数,那么输出所有正数的和. 例如:-2 11 -4 13 -5 6 -2,分为2段,11 -4 13一段,6一段,和为26. Input 第1行:2个数N和M,中间用空格分

[ACM] POJ 2479 Maximum sum (动态规划求不相交的两段子段和的最大值)

Maximum sum Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 33363   Accepted: 10330 Description Given a set of n integers: A={a1, a2,..., an}, we define a function d(A) as below: Your task is to calculate d(A). Input The input consists o

POJ 2479 Maximum sum

http://poj.org/problem?id=2479 题意: 给出一个整数串,求连续子串1和连续子串2,不相交并且串1加串2的和最大. 思路: 其实就是求最大连续和,题意要求就是求两段最大连续和.我们可以从左边和右边分别求最大连续和,代码中的dp_l[i]就是1~i的最大连续和,dp_r[i]则是i~n的最大连续和. 1 #include<iostream> 2 #include<string> 3 #include<cstring> 4 #include<

Maximum sum(poj 2479)

题意:给一段数列,将这个数列分成两部分,使两部分的最大子段和的和最大,输出和 /* 看数据没想到是(O)n的算法,求出从前向后的最大子段和和从后向前的最大子段和, 然后枚举断点. 第一次提交不小心折在数组最小值的赋值上…… */ #include<cstdio> #include<iostream> #include<cstring> #define M 50010 #define INF 1000000000 using namespace std; int a[M]

poj 2479 Maximum sum(递推)

?? 题意:给定n个数,求两段连续不重叠子段的最大和. 思路非常easy.把原串划为两段.求两段的连续最大子串和之和,这里要先预处理一下,用lmax数组表示1到i的最大连续子串和,用rmax数组表示n到i的最大连续子串和,这样将时间复杂度降为O(n). #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<iostream> #include&l

[poj 2479] Maximum sum -- 转载

转自 CSND 想看更多的解题报告: http://blog.csdn.net/wangjian8006/article/details/7870410                                      转载请注明出处:http://blog.csdn.net/wangjian8006 题目大意: 对于连续的整数和的串s1和s2,s1与s2不相交,使得s1+s2最大 解题方法: DP.  lt[i]代表以第i个元素结尾的串最大值  rt[i]代表以第i个元素开头的串的最大

POJ 2479 Maximum sum ( DP )

题目大意: 对整数串S,求其两个不相交的子串s1.s2,使得s1+s2的值最大. 方法:DP, lt[i]代表以第i个元素结尾的串最大值 rt[i]代表以第i个元素开头的串的最大值 那么设置一个rtm[i]代表取后i个元素之中最大连续子串的和 很显然,lt[i]=max(a[i],lt[i-1]+a[i]); rt[i]=max(a[i],rt[i+1]+a[i]); rtm[i]=max(rtm[i+1],rt[i]); #include <iostream> #include <cs

POJ 2479 Maximum sum(双向DP)

Maximum sum Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 36100   Accepted: 11213 Description Given a set of n integers: A={a1, a2,..., an}, we define a function d(A) as below: Your task is to calculate d(A). Input The input consists o

Poj 2479 Maximum sum【双向DP/最大连续和】

Maximum sum 题意:给定一个长度为N的数组,求两个连续的子序列,使得两个连续子序列的和最大. 分析:乍一看,跟最大连续和有点类似,但是,又有区别,因为对于这个题,考虑第i项两个连续子序列的最大和,不能仅仅由前i-1项递推得出,第i项两个连续子序列的最大和,与前i项和i以后的之间是存在关系的,因此这个题目是一个双向dp. 假如给定的序列为a0, a1, a2, a3, a4, ...... ,an,那么,对于任意第i项,我以第i个元素为分界点,用一个数组项pMax [i]来保存  区间