链接:https://ac.nowcoder.com/acm/contest/949/D
来源:牛客网
水果店里有 n个水果排成一列。店长要求顾客只能买一段连续的水果。
小阳对每个水果都有一个喜爱程度 ai,最终的满意度为他买到的水果的喜欢程度之和。
如果和为正(不管是正多少,只要大于 0即可),他就满意了。
小阳对每个水果都有一个喜爱程度 ai,最终的满意度为他买到的水果的喜欢程度之和。
如果和为正(不管是正多少,只要大于 0即可),他就满意了。
小阳想知道在他满意的条件下最多能买多少个水果。
你能帮帮他吗?输入描述:
第一行输入一个正整数 n,表示水果总数。第二行输入 n 个整数 ai,表示小阳对每个水果的喜爱程度。
输出描述:
一行一个整数表示结果。(如果 1 个水果都买不了,请输出 0)
备注:1≤n≤2×10^6,∣ai∣≤10^3
分析: 用前缀和, 要求sum[b]-sum[a]>0, 且b与a距离越大越好, 最开始的想法是单调栈, 保留一个递减序列, 因为若sum[i]<sum[i+1}, 只有保留 sum[i]的需要, 然后二分就好啦。 我看得别人的做法, 觉得很好很简洁(虽然复杂度相同); 从整体分析问题, 对sum前缀和排序, 相同的前缀,其下标大的在前面; 然后便利这个有序sum序列, 这样就保证了后面的sum大于前面的sum, 为了寻找最大的间距, 我们维护一个最小下标就好了 因为sum相同的时候, 下标大的在前面, 就排除掉了连续序列和为0的情况!
1 #include <bits/stdc++.h>
2 using namespace std;
3 const int N=2e6+7;
4 struct node {
5 int val;
6 int id;
7 bool operator<(const node& x) const {
8 if(val==x.val) return id>x.id;
9 else return val<x.val;
10 }
11 };
12 node t[N];
13 int n;
14 int main()
15 {
16 scanf("%d",&n);
17 for (int i=1;i<=n;i++) {
18 scanf("%d",&t[i].val);
19 t[i].val+=t[i-1].val;
20 t[i].id=i;
21 }
22 sort(t,t+1+n);
23 int min_id=n+7,ans=0;
24 for (int i=0;i<=n;i++) {
25 ans=max(ans, t[i].id-min_id);
26 min_id=min(t[i].id, min_id);
27 }
28 printf("%d\n",ans);
29 return 0;
30 }