51nod 3级算法题-1065

来源:互联网 发布:执信软件 编辑:程序博客网 时间:2024/06/02 02:56

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示例

84-15-2-126-2

Output示例

1

思路:
先求序列前缀和并标记序列号,再将前缀和进行排序。逐一比较大小相邻的两个数,当位置关系同大小关系一样,则说明区间 [ i,j ]和为正,取所有的区间中的最小值。

#include <iostream>#include <cstring>#include <string>#include <cstdio>#include <cstdlib>#include <cmath>#include <algorithm>#include <queue>#include <stack>#include <vector>#include <set>#include <map>using namespace std;#define endl "\n"const int maxn = 50000+10;struct Num{    long long val;    int pos;}a[maxn];bool cmp(Num A,Num B){    return A.val<B.val;}int main (){    std::ios::sync_with_stdio(false);    memset(a,0,sizeof(a));    int n;    cin>>n;    long long sum=0;    int x;    for(int i=1;i<=n;i++){        cin>>x;        sum+=x;        a[i].pos=i;        a[i].val=sum;    }    sort(a,a+n+1,cmp);    int flag=1;    sum=0;    for(int i=1;i<=n;i++){        if(a[i].val>a[i-1].val && a[i].pos>a[i-1].pos){            if(flag){                sum=a[i].val-a[i-1].val;                flag=0;            }else{                sum=min(sum,a[i].val-a[i-1].val);            }        }    }    cout<<sum<<endl;    return 0;}
0 0
原创粉丝点击