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

     P1121 环状最大两段子段和

    给出一段环状序列,选出其中连续不重叠且非空的两段使得这两段和最大。 n<=2e5

    输入样例#1: 复制
    7
    2 -4 3 -1 2 -4 3
    
    输出样例#1: 复制
    9

    题解:一道好题

    考虑两种情况,o代表选择

    ***ooo***ooo**

    正做一遍最大子段和,倒做一遍最大子段和两者相加

    ooo****ooo***oo

    用总的减去两段最小子段和就可以得到上述,把原序列变成负的,做一遍最大子段和OK

    #include<bits/stdc++.h>
    using namespace std;
    const int M = 2e5 + 10;
    int a[M], f[M], g[M], n;
    int solve(){
        int ret = -2e9;
        for(int i=1;i<=n;i++)f[i] = max(f[i-1],0) + a[i];
        for(int j=n;j;j--)g[j] = max(g[j+1],0) + a[j];
        for(int i=2;i<=n;i++)f[i] = max(f[i-1],f[i]);
        for(int j=n-1;j;j--)g[j] = max(g[j+1],g[j]);
        for(int i=1;i<=n-1;i++)
        ret = max(ret, f[i]+g[i+1]);
        return ret;
    }
    
    
    int main(){
        scanf("%d", &n);
        int sum=0, tot=0;
        for(int i=1;i<=n;i++)scanf("%d", &a[i]), sum += a[i], tot += a[i] > 0;
        int ans1=solve();
        if(tot==1) return !printf("%d
    ", ans1);
        for(int i=1;i<=n;i++)a[i]=-a[i];
        int ans2=sum+solve();
        if(!ans2) ans2 = -2e9;
        printf("%d
    ", max(ans1,ans2));
    }
    View Code
  • 相关阅读:
    公司真题-字节跳动
    全素组探求
    枚举
    求n个整数的最大公约数
    Ajax技术
    读文本文件
    JSTL标签库
    URL跟URi的区别
    常用的JSTL标签
    EL表达语言
  • 原文地址:https://www.cnblogs.com/EdSheeran/p/9904901.html
Copyright © 2011-2022 走看看