题目大意
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
具体思路
这道题用到了前缀和,开一个结构体数组记录前缀和以及前缀和的末尾元素的位置,然后sort一下
最后得到排好序的数组,如果后者的位置大于前者,那么就可以相减求出最小正字段
记得处理一下只有一个元素的情况
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 const int maxn=2*2e5; 5 long long ans,n; 6 7 struct stu{ 8 long long w; 9 int pos; 10 }a[maxn]; 11 bool cmp(stu a,stu b){ 12 return a.w<b.w; 13 14 } 15 int main(){ 16 ans=10000000; 17 cin>>n; 18 long long x; 19 for(int i=1;i<=n;i++){ 20 cin>>x; 21 a[i].pos=i; 22 if(x>0)ans=min(ans,x); 23 a[i].w=a[i-1].w+x; 24 25 } 26 27 sort(a+1,a+n+1,cmp); 28 if(a[1].w>0)ans=min(ans,a[1].w); 29 for(int i=2;i<=n;i++){ 30 if(a[i].w>0)ans=min(ans,a[i].w); 31 if(a[i-1].pos<a[i].pos){ 32 long long xx=a[i].w-a[i-1].w; 33 if(xx>0)ans=min(ans,xx); 34 } 35 } 36 cout<<ans<<endl; 37 38 39 40 }