zoukankan      html  css  js  c++  java
  • 最小正子段和

    N个整数组成的序列a[1],a[2],a[3],…,a[n],从中选出一个子序列(a[i],a[i+1],…a[j]),使这个子序列的和>0,并且这个和是所有和>0的子序列中最小的。

    例如:4,-1,5,-2,-1,2,6,-2。-1,5,-2,-1,序列和为1,是最小的。

     

    输入

    第1行:整数序列的长度N(2 <= N <= 50000)
    第2 - N+1行:N个整数

    输出

    输出最小正子段和。

    输入样例

    8
    4
    -1
    5
    -2
    -1
    2
    6
    -2

    输出样例

    1

    思路:

    虽然说遇到连续和会想到前缀和,但是这道题对前缀和的使用实在是太巧妙了! Orz大佬的思想:

    我们记录前缀和的位置pos,以及前缀和的值val

    然后对前缀和的值进行排序

    然后我们找相邻的点,如果满足前面的pos小于后面的pos,它们 val 的差大于0     那么我们就记录它们的val之差

    为什么是找相邻的点就可以了呢?

    解释一下为什么只需检查相邻2个数就可以,设ABC是排序后的结果,如果A同B不能组成序列,而A同C可以组成序列,那么B同C也可以组成序列,并且BC会是一个更优的解。

    略微证明下:

    因为A和B不能组成序列,那么B的pos 小于 A的pos。 因为A和C可以组成序列,那么C的pos 大于 A的pos 

    所以B和C肯定也可以组成序列!因为又是排序过了的,所以B和C的差值肯定是优于A和C的差值的

    具体代码:

     1 #include <iostream>
     2 #include <algorithm>
     3 #include <stdlib.h>
     4 #include <string>
     5 #include <string.h>
     6 #include <set>
     7 #include <queue>
     8 #include <stdbool.h>
     9 
    10 #define LL long long
    11 #define inf 0x3f3f3f3f
    12 using namespace std;
    13 const int MAXN=50005;
    14 
    15 typedef struct Node{
    16     LL val;
    17     int pos;
    18 }Node;
    19 
    20 Node a[MAXN] = {0};
    21 
    22 bool cmp(Node a,Node b)
    23 {
    24     return a.val < b.val;
    25 }
    26 
    27 
    28 int main()
    29 {
    30 #ifndef ONLINE_JUDGE
    31     freopen("../in.txt","r",stdin);
    32 #endif
    33     int n,flag;
    34     LL temp;
    35     LL sum = 0;
    36     scanf("%d",&n);
    37     a[0].val = 0;
    38     a[0].pos = 0;
    39     for (int i=1;i<=n;i++)
    40     {
    41         cin >> temp;
    42         sum += temp;
    43         a[i].val = sum;
    44         a[i].pos = i;
    45     }
    46     sort(a,a+1+n,cmp);
    47     LL res;
    48     flag = 0;
    49     for (int i=1;i<=n;i++)
    50     {
    51         if (a[i].pos-a[i-1].pos>0 && a[i].val-a[i-1].val>0)
    52         {
    53             if (flag == 0)
    54             {
    55                 res = a[i].val-a[i-1].val;
    56                 flag = 1;
    57             }
    58             else
    59             {
    60                 if ( a[i].val-a[i-1].val<res)
    61                     res = a[i].val-a[i-1].val;
    62             }
    63         }
    64     }
    65     cout << res << endl;
    66     return 0;
    67 }

  • 相关阅读:
    HTTP断点续传 规格严格
    Java Shutdown 规格严格
    linux 命令源码 规格严格
    JTable调整列宽 规格严格
    linux 多CPU 规格严格
    Hello can not find git path 规格严格
    Kill 规格严格
    拜拜牛人 规格严格
    Swing 规格严格
    Debugging hangs in JVM (on AIX but methodology applicable to other platforms) 规格严格
  • 原文地址:https://www.cnblogs.com/-Ackerman/p/11218294.html
Copyright © 2011-2022 走看看