• 最小正子段和


    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 }

  • 相关阅读:
    类函数指针
    resource for machine learning
    蒲丰投针与蒙特卡洛模拟
    IIS5、IIS6、IIS7的ASP.net 请求处理过程比较
    CMD 命令速查手册
    Process, Thread, STA, MTA, COM object
    在托管代码中设置断点(Windbg)
    SidebySide Execution
    .NET Framework 3.5 Architecture
    Overview of the .NET Framework
  • 原文地址:https://www.cnblogs.com/-Ackerman/p/11218294.html
Copyright © 2020-2023  润新知