最大子段和专题之最小正子段和

题目大意

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 }
原文地址:https://www.cnblogs.com/soda-ma/p/13125352.html