• 最小正子段和


    最小正子段和

    N个整数组成的序列a1,a2,a3,…,an,从中选出一个子段(ai,ai+1,…aj),使这个子段的和>0,并且这个和是所有和>0的子段中最小的。例如:4,-1,5,-2,-1,2,6,-2。-1,5,-2,-1,序列和为1,是最小的。

    Input
    第1行:整数序列的长度N(2 <= N <= 50000) 第2 - N+1行:N个整数
    Output
    输出最小正子段和。
    Sample Input

    8
    4
    -1
    5
    -2
    -1
    2
    6
    -2
    

    Sample Output

    1
    

    题目大意

    负数和正数都有的一个序列,求最小子段和

    思路分析

    一开始想用动规做但是发现需要用到的前面的状态不止一个,因为正负都有,每一段在加上后面的数字以后都会有成为答案的机会,所以想着想着果断放弃了
    所以考虑用前缀和,要是直接都跑一遍显然会炸,那肯定就需要优化一下:

    敲黑板

    • 首先用到前缀和数组,既然要求正子段和,就需要保证右端点的前缀和大于左端点的值
    • 将前缀和数组建立成一个结构体,记录前缀和的值和尾端元素的位置,这样就可保证右端点的前缀和大于左端点的值(但是需要用尾端位置进行一下判断,保证一个大的那一个在右端点),然后更新答案就好说了

    代码

    #include<iostream>
    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    const int N = 5e5+10;
    typedef long long ll;
    using namespace std;
    struct point{
        ll w; //w记录大小
        int v; //v记录位置
    }sum[N];
    int a[N];
    ll ans;
    bool cmp(point x,point y){
        return x.w<y.w;
    }
    int main(){
        int n;scanf("%d",&n);
        for (int i=1;i<=n;i++)scanf("%d",&a[i]);
        sum[1].w=a[1];
        for (int i=2;i<=n;i++){
            sum[i].w=sum[i-1].w+a[i];
            sum[i].v=i;
        }
        sort(sum+1,sum+1+n,cmp); //从小到大排序
        if (sum[1].w>0)  ans=sum[1].w; //如果最小的前缀和数组是正的,那它就有机会成为最小正子段和
        else ans=0x3f3f3f3f3f3f3f3f;
        for (int i=2;i<=n;i++){
            if (sum[i].w>0&&sum[i].w<ans)ans=sum[i].w; //还是直接用前缀和这一整段去更新
            if (sum[i].w>sum[i-1].w&&sum[i].v>sum[i-1].v&&(sum[i].w-sum[i-1].w<ans)) //对于不是从头开始的一段,遍历每两个相邻前缀和数组的差,就是它们中间一段的值,同时保证大的在右端
              ans=sum[i].w-sum[i-1].w;
        }
        printf("%lld",ans);
        return 0;
    }
    
  • 相关阅读:
    SVN安装
    MS SQL Server 查询元数据
    MS SQL Server 时间函数
    Codeforces 666E Forensic Examination (后缀自动机 + 线段树合并)
    2020牛客暑期多校训练营(第八场) H Hard String Problem
    2020牛客暑期多校训练营(第四场) B Count New String
    2020牛客暑期多校训练营(第四场) A Ancient Distance
    2020杭电多校第三场 1007 Tokitsukaze and Rescue
    codeforces 1037H
    2020牛客暑期多校训练营(第三场) H Sort the Strings Revision
  • 原文地址:https://www.cnblogs.com/hhhhalo/p/13086469.html
Copyright © 2020-2023  润新知