bzoj4586: [Usaco2016 Open]Landscaping

来源:互联网 发布:淘宝直播招聘主播吗 编辑:程序博客网 时间:2024/05/22 08:18

前言

FYC说牛头都是水题。。
身为一个非权限用户。。
我一搜usaco,就找到了这个。。
没想到这么神啊啊啊啊啊啊啊

解法1—–>费用流

当然,这个方法是会TLE的。。
WA不WA不知道,我也没写过。。
建图方法大概张这样

这里写图片描述
图不是我画的,所以很难看
有很多边没有画,自己脑补
好吧,可以忽略这个了

解法2——->堆+贪心

我在这里只讨论一种情况吧,那就是a<b的情况,a>b的是刚好相反的,a=b的就不用管了

首先,这题a,b很小,不是没有用的
我们需要枚举一下每一块草坪的决策时什么
有一下两种决策:
①直接移走,那么代价就是y
②和之前一个配合,也就是送去之前a>b那里
我们先介绍之前那个是买的,那么他的代价就是: u*z-i*z-x
然后当上式

#include<cstdio>#include<cstring>#include<queue>#include<algorithm>#include<iostream>using namespace std;typedef long long LL;LL n,x,y,z;priority_queue<int> a,b;//之前是流进的     之前是流出的 int main(){    scanf("%lld%lld%lld%lld",&n,&x,&y,&z);    LL ans=0;    for (LL u=1;u<=n;u++)    {        LL xx,yy;        scanf("%lld%lld",&xx,&yy);        if (xx>yy)//他是要流出去         {            for (LL i=1;i<=xx-yy;i++)            {                if (a.empty())//如果之前没有反悔的机会                    ans=ans+y,b.push(u*z+y);                else                {                    LL w=-a.top();                    if (u*z+w<y)//如果这样的代价更小一点                        ans=ans+u*z+w,a.pop(),b.push(u*z*2+w);                    else ans=ans+y,b.push(u*z+y);                }            }        }        else        {            for (LL i=1;i<=yy-xx;i++)            {                if (b.empty())                    ans=ans+x,a.push(u*z+x);                else                {                    LL w=-b.top();                    if (u*z+w<x)//如果这样的代价更小一点                        ans=ans+u*z+w,b.pop(),a.push(u*z*2+w);                    else ans=ans+x,a.push(u*z+x);                }            }        }    }    printf("%lld\n",ans);    return 0;}