zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    2021秋 数分B1笔记
    android逆向奇技淫巧二十三:自己写app调用x音关键so(未完待续)(八)
    android逆向奇技淫巧二十二:ida栈回溯加密算法跟踪(未完待续)(七)
    http tcp websocket
    location.reload
    event.preventDefault
    document.querySelector
    造成播放端卡顿的原因
    引入外部组件 Vue.use()和Vue.component()
    Interpolation
  • 原文地址:https://www.cnblogs.com/hua-dong/p/9139378.html
Copyright © 2011-2022 走看看