• 51nod-1065:最小正子段和(STL)


    N个整数组成的序列a11,a22,a33,…,ann,从中选出一个子序列(aii,ai+1i+1,…ajj),使这个子序列的和>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

    思路:对于每个前缀和,找到左边的u最大的小于sum[i]的数,两种写法:

    第一种手动维护有序数列。

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    const int maxn=50010;
    ll a[maxn];
    vector<ll>v;
    int main()
    {
        ll N,i,j,ans=-1;
        scanf("%lld",&N);
        v.push_back(0);
        for(i=1;i<=N;i++){
            scanf("%lld",&a[i]);
            a[i]+=a[i-1];
            int pos=lower_bound(v.begin(),v.end(),a[i])-v.begin();
            if(pos-1>=0&&(ans==-1||ans>a[i]-v[pos-1])) ans=a[i]-v[pos-1];
            pos=upper_bound(v.begin(),v.end(),a[i])-v.begin();
            v.insert(v.begin()+pos,a[i]);
        }
        printf("%lld
    ",ans);
        return 0;
    }

    第二种用lower_bound+set

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    const ll inf=1e18;
    const int maxn=50010;
    ll a[maxn];
    set<ll>s;
    int main()
    {
        ll N,i,j,ans=inf;
        scanf("%lld",&N);
        for(i=1;i<=N;i++){
            scanf("%lld",&a[i]);
            a[i]+=a[i-1];
        }
        s.insert(a[N]);
        for(i=N-1;i>=0;i--){
            ll t=*s.lower_bound(a[i]+1);
            if(t-a[i]>0) ans=min(ans,t-a[i]);
            s.insert(a[i]); 
        }
        printf("%lld
    ",ans);
        return 0;
    }
  • 相关阅读:
    .net Framework 4.5 MVC4 + RabbitMQ
    阿里云飞天系统的技术架构(转)
    ORA12899错误解决记录
    网络通讯函数测试记录
    .应该用CreateThread还是_beginthreadex(), 为什么?( 转载)
    发挥v$SQL视图的作用(oracle)
    ClickHouse笔记
    MySQL字段是JsonArray格式怎么查询数据
    Base64编码保存为图片,java工具类
    java两个线程交替打印数字
  • 原文地址:https://www.cnblogs.com/hua-dong/p/9139378.html
Copyright © 2020-2023  润新知