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

    我们用前缀和的思想来解决这个问题,我们定义一个结构体,在结构体内保存前缀和和位置,按照前缀和的升序排序,排序后,最小的正字段和只可能是相邻的两个差。
    #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;
    }

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

  • 相关阅读:
    多线程的多核分配问题验证
    C++C#联合调试
    UNITY 手游(安卓)如何使用C/C++代码
    关于C#内存释放的BUG?
    日期转换
    深度剖析目标检测算法YOLOV4
    2. 使用Shell能做什么
    【Jmeter】之进行接口批量压力测试
    MongoDB-ChangeStream使用笔记
    Mongo-BI(bi-connector)配置使用笔记
  • 原文地址:https://www.cnblogs.com/LightyaChoo/p/13086345.html
Copyright © 2011-2022 走看看