zoukankan      html  css  js  c++  java
  • 【u124】环状最大两段子段和

    Time Limit: 1 second
    Memory Limit: 128 MB
    【问题描述】

    给出一段环状序列,即认为A[1]和A[N]是相邻的,选出其中连续不重叠且非空的两段使得这两段和最大。

    【输入格式】

    输入文件maxsum2.in的第一行是一个正整数N,表示了序列的长度。 第2行包含N个绝对值不大于10000的整数A[i],描述了这段序列,第一个数和第N个数是相邻的。
    【输出格式】

    输入文件maxsum2.out仅包括1个整数,为最大的两段子段和是多少。
    【数据规模】

    对于40%的数据,有2 ≤ N ≤ 2000。 对于100%的数据,有N ≤ 200000。
    Sample Input1

    7

    2 -4 3 -1 2 -4 3

    Sample Output1

    9

    【样例解释】

    一段为3 –1 2,一段为3 2

    *2 -4 *3 *-1 *2 -4 *3

    【题目链接】:http://noi.qz5z.com/viewtask.asp?id=u124

    【题解】

    假设最后的答案区间被涂上红色;则最后答案一定是以下两种形式;(把环看成是直线);
    这里写图片描述
    这里写图片描述
    对于第一种情况,只要枚举两个区间的断点就可以了;
    枚举前要用最大子段和问题的普通形式的数组弄个前缀和和后缀和;
    枚举的时候左边和右边直接加起来就是两个红色部分的了;
    而对于第二种情况
    我们可以转换成求中间两段黑色的部分;让它的和最小;即求两段子段和最小;然后用总数减去它就是最大的了;
    两种情况取最大值就好;
    用第二种方法求解是有条件的;
    即数组中的正数的个数要大于1个;
    比如
    没有正数
    5
    -1 -1 -1 -1 -1
    如果用了第二种答案为0(程序认为黑色部分两段和的最小值为-5而总和为-5…);正确答案是-2,第一种才能求出来;
    只有一个正数也不行
    5
    -1 -1 -1 -1 5
    第二种答案为5(两个最小部分和为-4,总和为1);但是如果答案为5的话就没有选出两段出来,因此正确答案为第一种求出来的4才对;

    【完整代码】

    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <set>
    #include <map>
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <queue>
    #include <vector>
    #include <stack>
    #include <string>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define LL long long
    #define rep1(i,a,b) for (int i = a;i <= b;i++)
    #define rep2(i,a,b) for (int i = a;i >= b;i--)
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    
    typedef pair<int,int> pii;
    typedef pair<LL,LL> pll;
    
    void rel(LL &r)
    {
        r = 0;
        char t = getchar();
        while (!isdigit(t) && t!='-') t = getchar();
        LL sign = 1;
        if (t == '-')sign = -1;
        while (!isdigit(t)) t = getchar();
        while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
        r = r*sign;
    }
    
    void rei(int &r)
    {
        r = 0;
        char t = getchar();
        while (!isdigit(t)&&t!='-') t = getchar();
        int sign = 1;
        if (t == '-')sign = -1;
        while (!isdigit(t)) t = getchar();
        while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
        r = r*sign;
    }
    
    const int MAXN = 2e5+100;
    const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
    const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
    const double pi = acos(-1.0);
    
    int n;
    int pltor[MAXN],ltor[MAXN],prtol[MAXN],rtol[MAXN],a[MAXN];
    int pltor1[MAXN],ltor1[MAXN],prtol1[MAXN],rtol1[MAXN];
    
    int main()
    {
        //freopen("D:\rush.txt","r",stdin);
        int total=0,cnt=0;
        rei(n);
        rep1(i,1,n)
        {
            rei(a[i]);
            if (a[i]>0)
                cnt++;
            total+=a[i];
        }
        pltor[0]=-21e8;
        pltor1[0]=21e8;
        rep1(i,1,n)
        {
            ltor[i] = max(a[i],ltor[i-1]+a[i]);
            pltor[i] = max(pltor[i-1],ltor[i]);
            ltor1[i] = min(a[i],ltor1[i-1]+a[i]);
            pltor1[i] = min(pltor1[i-1],ltor1[i]);
        }
        prtol[n+1]=-21e8;
        prtol1[n+1]=21e8;
        rep2(i,n,1)
        {
            rtol[i] = max(a[i],rtol[i+1]+a[i]);
            prtol[i] = max(prtol[i+1],rtol[i]);
            rtol1[i] = min(a[i],rtol1[i+1]+a[i]);
            prtol1[i] = min(prtol1[i+1],rtol1[i]);
        }
        int ans1 = -21e8,ans2=21e8;
        rep1(i,1,n-1)
        {
            int temp = pltor[i]+prtol[i+1];
            ans1 = max(ans1,temp);
            temp = pltor1[i]+prtol1[i+1];
            ans2 = min(ans2,temp);
        }
        if (cnt>1 && total-ans2>ans1)
            ans1 = total-ans2;
        printf("%d
    ",ans1);
        return 0;
    }
  • 相关阅读:
    android api 中文 (74)—— AdapterView.AdapterContextMenuInfo
    Android API 中文(76)——AdapterView.OnItemLongClickListener
    Android 中文api (81)——InputMethod [输入法]
    android 中文 api (87) —— BaseInputConnection
    Android 中文API合集(4)(102篇)(chm格式)
    Android中文API(97)—— ContextMenu
    android api 中文 (75)—— AdapterView.OnItemClickListener
    android 中文api (84) —— TrafficStats
    Windows XP 上安装 Bind9
    数据库索引实例之三
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7626907.html
Copyright © 2011-2022 走看看