zoukankan      html  css  js  c++  java
  • 最大子段和(交换)

    题意:

      给你一个序列找到交换一次后的最大字段和(所有交换方式中最大的)

    分析:

      首先我们这么想,我们要最后要的答案是由某个区间和区间左边交换一个或和区间右边交换一个或者不交换(内部交换或外部交换)。

      至于不交换,我们直接o(n)搞过。

      然后就是向左(向右类似,只要把序列倒过来跑一边就好了)交换,我们可以得到:ans=max(sum[i]-sum[j]-a[k1]+a[k2])(i>j,j<k1<=i,k2<=j),我们只要n的4次方枚举就好了。

      可是我们怎么优化呢?

      我们加一个括号:sum[i]-(sum[j]+a[k1]-a[k2])(范围略去),然后我们就可以n的效率枚举i,然后提前预处理一下min(sum[j]+a[k1]-a[k2]),用一个数组记录一下min(枚举合法的j,k1,k2),然后求一下前缀max就好了,效率到了n的3次方,然后类似的,我们只需要n的效率枚举k1,然后n×n求sum[j]-a[k2]的最小值,效率变成了n×n,最后再n的效率枚举j,n的效率求k2的最小值,效率变成了n,最后整合到一起就好了。

      代码:

      

    #include <cstdio>
    #include <string>
    using namespace std;
    #define ll long long
    const int maxn=5e4+10;
    const ll inf=1e18;
    
    ll a[maxn];
    ll sum[maxn];
    ll b[maxn];
    int main(){
        int n;
        scanf("%d",&n);
        ll mi=0ll,ans=-inf,nowj=0ll,ma=-inf;
        for(int i=1;i<=n;i++){
            scanf("%lld",&a[i]);
            sum[i]=sum[i-1]+a[i];
            ans=max(ans,sum[i]-nowj);
            nowj=min(nowj,a[i]+mi);
            ma=max(ma,a[i]);
            mi=min(sum[i]-ma,mi);
        }
        mi=0ll;
        for(int i=1;i<=n;i++){
            ans=max(ans,sum[i]-mi);
            mi=min(sum[i],mi);
        }
        for(int i=1;i<=n;i++)
            b[i]=a[n-i+1];
        for(int i=1;i<=n;i++)
            a[i]=b[i];
        mi=0ll,nowj=0ll,ma=-inf;
        for(int i=1;i<=n;i++){
            sum[i]=sum[i-1]+a[i];
            ans=max(ans,sum[i]-nowj);
            nowj=min(nowj,a[i]+mi);
            ma=max(ma,a[i]);
            mi=min(sum[i]-ma,mi);
        }
        printf("%lld",ans);
        return 0;
    }

      

  • 相关阅读:
    BZOJ 4318: OSU!
    BZOJ 3450: Tyvj1952 Easy
    BZOJ 1426: 收集邮票
    BZOJ 1415: [Noi2005]聪聪和可可
    BZOJ 1778: [Usaco2010 Hol]Dotp 驱逐猪猡
    BZOJ 3270: 博物馆
    BZOJ 3143: [Hnoi2013]游走
    BZOJ 3166: [Heoi2013]Alo
    BZOJ 3261: 最大异或和
    BZOJ 1022: [SHOI2008]小约翰的游戏John
  • 原文地址:https://www.cnblogs.com/wish-all-ac/p/13112002.html
Copyright © 2011-2022 走看看