51nod1065 最小正子段和

这里写图片描述

经典的题目

复习一下快排的写法:

int quickSort(int a[],int low,int high)
{
    int tmp=a[low];
    while(low<high)
    {
        while(low<high&&a[high]>tmp)high--;
        a[low]=a[high];
        while(low<high&&tmp>a[low])low++;
        a[high]=a[low]; 

    }
    a[low]=tmp; 
    return low;


}

void QSort(int a[],int low,int high)
{
    if(low<high)
    {
        int tmp=quickSort(a,low,high)
        QSort(a,low,tmp);
        QSort(a,tmp+1,high);
    }

}


引用出题人的原话:

先求一下从第一位开始的到第i位的累加, 4,-1,5,-2,-1,2,6,-2 => 4 3 8 6 5 7 13 11

对这个累加的数列排个序,然后只要判断邻近的两个数是否可以组成序列,比如4和3就不可以,因为4 >
3而4对应下标为0,3对应为1。4和5就可以

特别判断当前位是否也是最小值。。。。也就是从“0-当前位”

#include <bits/stdc++.h>

using namespace std;

#define LL long long
const LL MAXN=5e4+10;
const LL INF=99999999;
struct Node
{
    LL rk,val;
}node[MAXN];
LL a[MAXN];


//快排
LL quickSort(Node a[],LL low,LL high)
{
    //low=0,high=len-1;
    Node privot=a[low];
    while(low<high)
    {
        while(low<high&&a[high].val>=privot.val)high--;
        a[low]=a[high];
        while(low<high&&a[low].val<=privot.val)low++;
        a[high]=a[low];
    }
    a[low]=privot;
    return low;
}


//递归快排
LL QSort(Node a[],LL low,LL high)
{
    if(low<high)
    {
        LL tmp=quickSort(a,low,high);
        QSort(a,low,tmp);
        QSort(a,tmp+1,high);
    }
}

void getMin(LL a[],LL len)
{
    Node b[len];
    LL sum=0;
    for(LL i=0;i<len;i++)
    {
        sum+=a[i];
        b[i].val=sum;
        b[i].rk=i;
    }
    QSort(b,0,len-1);
    LL minVal=b[0].val>0?b[0].val:INF;
    for(LL i=1;i<len;i++)
    {
        if(b[i].val>0)
            minVal=min(minVal,b[i].val);

        if(b[i].rk>b[i-1].rk)
        {
            LL tmp=b[i].val-b[i-1].val;
            if(tmp>0&&tmp<minVal)
            {
                minVal=tmp;

            }

        }
    }
    cout<<minVal;
}

int main()
{
    LL n;
    cin>>n;
    for(LL i=0;i<n;i++)
        cin>>a[i];
    getMin(a,n);
    return 0;
}
原文地址:https://www.cnblogs.com/bryce1010/p/9386933.html