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


    题目大意

    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 }
  • 相关阅读:
    [AH2017/HNOI2017]礼物
    [八省联考2018]林克卡特树lct
    [洛谷P4847]银河英雄传说V2
    [洛谷P4999]烦人的数学作业
    [洛谷P4171][JSOI2010]满汉全席
    [CF785E]Anton and Permutation
    [洛谷P2511][HAOI2008]木棍分割
    [洛谷P4430]小猴打架
    [UVA307]小木棍 Sticks
    [LOJ #6433]「PKUSC2018」最大前缀和
  • 原文地址:https://www.cnblogs.com/soda-ma/p/13125352.html
Copyright © 2020-2023  润新知