• 最小正字段和


    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

    我们用前缀和的思想来解决这个问题,我们定义一个结构体,在结构体内保存前缀和和位置,按照前缀和的升序排序,排序后,最小的正字段和只可能是相邻的两个差。
    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    const int n=1e6;
    int a[n];
    ll N;
    struct Node{
        ll w;
        int p;
    }e[50005];
    
    bool cmp(Node A,Node B){
        return A.w<B.w;
    }
    
    int main(){
        scanf("%lld",&N);
        for(int i=1;i<=N;i++){
            scanf("%d",&a[i]);
            e[i].w=a[i];
        }
        e[1].w=a[1];
        for(int i=2;i<=N;i++){
            e[i].w=e[i-1].w+a[i];
            e[i].p=i;
        }
        sort(e+1,e+1+N,cmp);
        ll ans;
        if(e[1].w>0)ans=e[1].w;
        else ans=100000000;
        for(int i=2;i<=N;i++){
            if(e[i].w>0&&ans>e[i].w){
                ans=e[i].w;
            }
            if(e[i].w>e[i-1].w&&e[i].p>e[i-1].p&&(e[i].w-e[i-1].w)<ans){//不要忘了对位置进行判断!!!
                ans=e[i].w-e[i-1].w;
            }
        }
        printf("%lld
    ",ans);
        return 0;
    }

    大家有疑问随时可以问的吖!!

  • 相关阅读:
    CUDA从入门到精通
    [Network] 计算机网络基础知识总结
    第三章 需求工程概论
    jsp学习
    算法——递推算法
    大话设计模式读书笔记--文章汇总
    轻松学SQL Server数据库
    Oracle数据库建表+添加数据练习
    《C#图解教程》 总览
    php发送get、post请求的6种方法简明总结
  • 原文地址:https://www.cnblogs.com/LightyaChoo/p/13086345.html
Copyright © 2020-2023  润新知