zoukankan      html  css  js  c++  java
  • 最大子段和专题之最小正子段和

    题目大意

    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 }
  • 相关阅读:
    【模板】扩展中国剩余定理(EXCRT)
    战略游戏(树形DP)
    二叉苹果树(树形DP)
    货车运输(最大生成树,LCA)
    [CQOI2016]密钥破解
    Pollard-Rho算法andMiller_Rabin算法
    [TJOI2009]猜数字(中国剩余定理)
    中国剩余定理(学习笔记)
    线段树 Segment Tree
    辗转相除法
  • 原文地址:https://www.cnblogs.com/soda-ma/p/13125352.html
Copyright © 2011-2022 走看看