题解 滑稽树前做游戏,滑稽树后做交易 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的主要内容,如果未能解决你的问题,请参考以下文章

python(pygame)滑稽大战(类似飞机大战) 教程

小米游戏加速原神gpu设置

U68464 滑稽树上滑稽果(guo)

UOJ370 滑稽树上滑稽果 状压DP

dp uoj370 滑稽树上滑稽果

背包 贪心