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,是最小的。

<button class="btn btn&#45;xs btn&#45;white m&#45;t&#45;sm"> 收起</button>
 

输入

第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 }