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

    首先处理出前缀和数组。在前缀和数组中,我们要求的是dmin=sum[i]-sum[j](当 i>j && sum[i]-sum[j]>0 时)。
    那么就可以用一个新的结构体来存储每个sum[i]和它的编号。即 b[i].id=i; b[i].w=sum[i];
    此时sort之后我们就有了一个按照 前缀和大小 排序的带有顺序的结构体。
    之后再用一个循环去挨个遍历找相邻连个的最下差值。

    注意当 b[i].w==b[j].w 的时候,我们要让 id 大的在前面。这样的话,当有很多前缀和都相等的时候,比如 2 3 3 3 3 3 3 4,就避免了许多不必要的比较。
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <cmath>
    const int MAXN = 50000+3;
    using namespace std;
    typedef long long ll;
    
    int n,Min; ll a[MAXN],sum[MAXN],ans;
    
    struct B{int id;ll w;}b[MAXN];
    
    bool Com(B x,B y){
        if(x.w==y.w) return (x.id>y.id);
        return (x.w<y.w);
    }
    
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%lld",&a[i]);
            b[i].w=sum[i]=sum[i-1]+a[i];
            b[i].id=i;
        }
        
        sort(b+1,b+1+n,Com);
        if(b[1].w>0) ans=b[1].w;//注意不要忽略以a[1]开头的一段区间!!!
        else ans=0x3f3f3f3f3f3f3f3f;
        
        for(int i=2;i<=n;i++){
            int d=b[i].w-b[i-1].w;
            if(b[i].w>0 && ans>b[i].w) ans=b[i].w;//注意不要忽略以a[1]开头的一段区间!!!
            if(b[i].id>b[i-1].id && d>0 && ans>d){
                ans=(ll)b[i].w-b[i-1].w;
            }
        }
        printf("%lld",ans);
        return 0;
    }
    
    
  • 相关阅读:
    张拥军:解码商品期货投资实战应用 2011年06月02日
    罗小奔:谈一下最近商品期货套利的几个机会
    罗小奔:商品期货套利当前之我见
    leetcode -- Binary Tree Preorder Traversal
    leetcode -- Linked List Cycle II
    leetcode -- Linked List Cycle
    [转载]2014年10月26完美世界校招两道java题
    [转载]SQL truncate 、delete与drop区别
    [转载]会引起全表扫描的几种SQL
    [转载]Linux I/O 调度方法
  • 原文地址:https://www.cnblogs.com/Siegfried-L/p/13086791.html
Copyright © 2011-2022 走看看