• 51nod 1065 最小正子段和


    1065 最小正子段和

    N个整数组成的序列a[1],a[2],a[3],…,a[n],从中选出一个子序列(a[i],a[i+1],…a[j]),使这个子序列的和>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
    输出最小正子段和。
    Input示例
    8
    4
    -1
    5
    -2
    -1
    2
    6
    -2
    Output示例
    1
    ———————————————————————————
    这道题维护一下前缀和 只要枚举一下区间右端点 然后求前面的比他小的最接近他的就好辣
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<set>
    #define LL long long
    using namespace std;
    const int M=50007;
    const LL inf=1e15;
    int read(){
        LL ans=0,f=1,c=getchar();
        while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
        return ans*f;
    }
    int n;
    LL sum[M],ans=inf;
    set<LL>tr;
    int main(){
        n=read();
        tr.insert(0);
        for(int i=1;i<=n;i++){    
            sum[i]=sum[i-1]+read();
            set<LL>::iterator it=tr.lower_bound(sum[i]);
            if(it!=tr.begin()) ans=min(ans,sum[i]- *--it);
            tr.insert(sum[i]);
        }printf("%lld
    ",ans);
        return 0;
    }
    View Code

    当然也可以归并排序(其实是分治

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<set>
    #define LL long long
    using namespace std;
    const int M=50007;
    const LL inf=1e15;
    int read(){
        LL ans=0,f=1,c=getchar();
        while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
        return ans*f;
    }
    int n;
    LL s[M],ans=inf,c[M];
    void merge(int l,int r){
        if(l==r) return ;
        int mid=(l+r)>>1;
        merge(l,mid); merge(mid+1,r);
        int cnt=l,cntl=l,cntr=mid+1;
        while(cntl<=mid&&cntr<=r){
            if(s[cntl]<s[cntr]) ans=min(ans,s[cntr]-s[cntl]),c[cnt++]=s[cntl++];
            else c[cnt++]=s[cntr++];
        }
        while(cntl<=mid) c[cnt++]=s[cntl++];
        while(cntr<=r) c[cnt++]=s[cntr++];
        for(int i=l;i<=r;i++) s[i]=c[i];
    }
    int main(){
        n=read();
        for(int i=1;i<=n;i++) s[i]=s[i-1]+read();
        merge(0,n);
        printf("%lld
    ",ans);
        return 0;
    }
    View Code
     
  • 相关阅读:
    python 包与模块
    互斥锁与自旋锁
    TCP三次握手四次挥手
    缓存击穿、缓存穿透、缓存雪崩
    五种IO模型
    MySQL使用mysqldump进行数据备份
    golang数据库连接池参数设置
    golang代码文件目录组织、包目录组织学习笔记
    【转】如何用Vim提高开发效率
    emacs显示行号
  • 原文地址:https://www.cnblogs.com/lyzuikeai/p/7444501.html
Copyright © 2020-2023  润新知