Luogu P3826 [NOI2017]蔬菜

题意

好繁琐啊,自己去看。

题解

这题好神啊,口胡都没口胡出来,还是看着 yyb 的题解写出来的。

首先我不会费用流。

众所周知这个蔬菜变质的问题很烦对吧,我们不如时间倒流一下,求出最后一天能卖多少钱,然后每一天给你进一些蔬菜再推出每一天的答案。

考虑贪心。假设所有蔬菜不会变质,那么一定是卖那些贵的。所以说对于每一天来说贵的一定不会比便宜的卖的晚。

有了这个结论之后,我们能从第 (p) 天的答案推到第 (p-1) 天的答案。因为第 (p) 天能卖的蔬菜第 (p-1) 天也能卖,具体来说就是把利润最小的 (m) 个蔬菜扔掉换成别的就好了。

所以说,关于最后一天的处理,我们可以拿个堆把所有能卖的蔬菜维护一下,然后时间倒流来暴力模拟,每一天会加进来一些蔬菜,然后贪心取一下就好了。

(p) 天推到 (p-1) 天也是可以用一个堆来维护的,维护方法也是差不太多的,只要注意一下第一次卖有额外的收益就好了。

代码

#include<bits/stdc++.h>
using namespace std;
typedef int ll;
typedef long long int li;
const ll MAXN=2e5+51;
ll test,n,kk,r,res;
ll x[MAXN],f[MAXN],mx[MAXN];
inline ll read()
{
    register ll num=0,neg=1;
    register char ch=getchar();
    while(!isdigit(ch)&&ch!='-')
    {
        ch=getchar();
    }
    if(ch=='-')
    {
        neg=-1;
        ch=getchar();
    }
    while(isdigit(ch))
    {
        num=(num<<3)+(num<<1)+(ch-'0');
        ch=getchar();
    }
    return num*neg;
}
inline void solve()
{
    n=read(),kk=read();
    for(register int i=1;i<=n;i++)
    {
        x[i]=read();
    }
    for(register int i=1;i<=n;i++)
    {
        read();
    }
    sort(x+1,x+n+1),r=1,res=0,f[n+1]=mx[n+1]=0;
    for(register int i=1;i<=n;i++)
    {
        while(r<n&&x[r+1]-x[i]<=kk)
        {
            r++;
        }
        f[i]=r-i+1;
    }
    for(register int i=n;i;i--)
    {
        mx[i]=max(mx[i+1],f[i]);
    }
    for(register int i=1;i<=n;i++)
    {
        res=max(res,f[i]+mx[i+f[i]]);
    }
    printf("%d
",res);
}
int main()
{
    test=read();
    for(register int i=0;i<test;i++)
    {
        solve();
    }
}
原文地址:https://www.cnblogs.com/Karry5307/p/13736538.html