题解 滑稽树前做游戏,滑稽树后做交易 trade
Posted mxdh
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了题解 滑稽树前做游戏,滑稽树后做交易 trade相关的知识,希望对你有一定的参考价值。
题目名称我就不吐槽了。。。
题目描述
滑稽树前做游戏,滑稽树后做交易
(trade.cpp,3000ms,1024MB)
题目描述
滑稽果被排成一列,poison 的 lsr 要求每个顾客只能买一段连续的区间。
sxd 来这里买滑稽果,他对每个滑稽果都有一个喜爱程度 Ai 是一个整数,-100≤Ai≤100,
并保证∑Ai <=2147483647,最终的满意度为所有他买到的滑稽果的喜欢程度之和,如果和
为正(不管是正多少,只要大于 0 即可),则他满意了。
现在 sxd 想知道在他满意的条件下最多能买到多少滑稽果。
输入描述
第一行一个正整数 n,表示 lsr 一共摘了 n 个滑稽果。
第二行 n 个整数,每个整数 Ai 表示 sxd 第 i 个滑稽果的喜爱程度为多少。
输出描述
一行一个正整数 ans 表示在 sxd 满意的条件下最多能买到多少滑稽果
输入样例
5
0 0 -7 -6 1
输出样例
1
数据范围及提示
对于 30%的数据,n<=5*10^3
对于 60%的数据,n<=10^5
对于所有数据,n<=3*10^7
请注意本题的内存限制,完成代码后请务必计算一下你程序的内存是否超限。
由于本题的输入过大,请必须使用基于 fread 的输入模板,见题目目录下的 fastIO.cpp
题解
区间伸缩(尺取法)
代码
ver.0
#include <cstdio>
#include <algorithm>
#include <cctype>
using std::max;
using std::min;
const int N=30000000;
int a[N],sum[N+1],s[N+1];
inline char gc()
{
static char buf[1<<12],*p1=buf,*p2=buf;
return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,1<<12,stdin),p1==p2)?EOF:*p1++;
}
#define dd c = gc()
inline int read()
{
static int x;
x = 0;
int dd;
bool f = false;
for(; !isdigit(c); dd)
if(c == '-')
f = true;
for(; isdigit(c); dd)
x = (x<<1) + (x<<3) + (c^48);
if(f)
x = -x;
return x;
}
#undef dd
int main()
{
freopen("trade.in","r",stdin);
freopen("trade.out","w",stdout);
int n,ans=0,r=0;
n=read();
for (int i=0;i<n;++i) a[i]=read();
for (int i=n-1;~i;--i)
{
sum[i]=sum[i+1]+a[i];
s[i]=min(sum[i],s[i+1]);//s[n]=0,代表取从i开始取全部,需要更新
}
for (int i=0;i<n;++i)
{
r=max(r,i+1);
while (r<=n&&s[r]<sum[i])//到n为止,代表取从i开始取全部,需要更新
{
ans=max(ans,r-i);
++r;
}
if (r==n) break;
}
printf("%d",ans);
return 0;
}
ver.1 优化
#include <cctype>
#include <cstdio>
const int N = 30000000;
int sum[N + 1], s[N + 1];
inline char gc()
{
static char buf[1 << 24], *p1 = buf, *p2 = buf;
return (p1 == p2) && (p2 = (p1 = buf) + fread(buf, 1, 1 << 24, stdin), p1 == p2) ? EOF : *p1++;
}
#define dd c = gc()
inline int read()
{
static int x;
x = 0;
int dd;
bool f = false;
for (; !isdigit(c); dd)
if (c == '-')
f = true;
for (; isdigit(c); dd)
x = (x << 1) + (x << 3) + (c ^ 48);
return f ? -x : x;
}
#undef dd
inline int max(int x, int y)
{
return x > y ? x : y;
}
int main()
{
freopen("trade.in", "r", stdin);
freopen("trade.out", "w", stdout);
int n, ans = 0, r = 1;
n = read();
sum[0] = read();
for (int i = 1; i < n; ++i)
sum[i] = sum[i - 1] + read();
s[n - 1] = sum[n - 1];
for (int i = n - 2; ~i; --i)
s[i] = max(sum[i], s[i + 1]);
for (int i = 0; i < n && r < n; ++i, ++r)
{
if (n - i <= ans)
break;
if (s[r] <= sum[i])
continue;
while (r <= n && s[r] > sum[i])
++r;
ans = r - 1 - i;
}
printf("%d", ans);
return 0;
}
以上是关于题解 滑稽树前做游戏,滑稽树后做交易 trade的主要内容,如果未能解决你的问题,请参考以下文章