ZOJ 2592 Think Positive ——(xjbg)

  做法是,先求出前缀和pre。然后枚举端点i,[i+1,n]中pre最小的找出来,减去pre[i-1]大于0,这是第一个条件;第二个条件是,从i开始的后缀和和i之前的最小的一个pre相加大于0。只要满足这两个条件那么这个端点就是可行的。显然找这两个区间的最值都是可以用数组线性维护的,因此总体复杂度是O(n)的。

  代码如下:

 1 #include <stdio.h>
 2 #include <algorithm>
 3 #include <algorithm>
 4 using namespace std;
 5 const int N = 2e5 + 5;
 6 
 7 int a[N];
 8 int pre[N],suf[N];
 9 int min_pre_qian[N],min_pre_hou[N];
10 
11 int main()
12 {
13     int T;
14     scanf("%d",&T);
15     while(T--)
16     {
17         int n;
18         scanf("%d",&n);
19         for(int i=1;i<=n;i++)
20         {
21             scanf("%d",a+i),pre[i] = pre[i-1] + a[i];
22             if(i == 1) min_pre_qian[i] = pre[1];
23             else min_pre_qian[i] = min(pre[i], min_pre_qian[i-1]);
24         }
25         suf[n+1] = 0;
26         for(int i=n;i>=1;i--)
27         {
28             suf[i] = suf[i+1] + a[i];
29             if(i == n) min_pre_hou[i] = pre[i];
30             else min_pre_hou[i] = min(min_pre_hou[i+1], pre[i]);
31             //min_suf[i] = min(suf[i], min_suf[i+1]);
32         }
33         int ans = 0;
34         for(int i=1;i<=n;i++)
35         {
36             //printf("%d %d %d %d %d ??
",i,min_pre_hou[i],pre[i-1],suf[i],max_pre_qian[i-1]);
37             if(min_pre_hou[i] - pre[i-1] > 0 && suf[i] + min_pre_qian[i-1] > 0)
38             {
39                 ans++;
40             }
41         }
42         printf("%d
",ans);
43     }
44 }
原文地址:https://www.cnblogs.com/zzyDS/p/6637065.html