BZOJ 1229 [USACO2008 Nov]toy 玩具(三分+贪心)

【题木链接】 http://www.lydsy.com/JudgeOnline/problem.php?id=1229

【题目大意】

  每天对玩具都有一定的需求ni,每天可以花f价值每条购买玩具,
  当天用完的玩具可以花费fA价值每个通过快消毒在A天之后得到一条可用的,
  也可以通过花费fB价值每个,通过慢消毒在B天之后获得可用的
  问满足每天需求所用的最小花费。

【题解】

  这是纸巾问题的费用流模型,费用流做法见 BZOJ 1221 [HNOI2001] 软件开发

  但是我们发现N=100000的规模完全无法用费用流解决
  我们发现在最小费用最大流的过程中,每次的最短路长度不降,
  最短路是费用的差分值,所以一阶导不下降,那么费用随流量变化的函数是单峰的,
  可以三分,三分之后的验证可以通过贪心来实现,
  我们先假设把所有的毛巾快洗掉,到后面的天数发现之前决定快洗的毛巾放到慢洗里面也可以
  那就把这个点拿出来加入到慢洗完成的队伍。

【代码】

#include <cstdio>
#include <algorithm>
using namespace std;
const int INF=0x3f3f3f3f,N=100010;
int a[N],A,B,f,fA,fB,n;
struct data{int x,y;}d[N],s[N],q[N];
int F(int x){
    int ret=(f-fB)*x,l,r,sl,sr,ql,qr;
    l=sl=ql=r=1; sr=qr=0;
    d[l].x=-INF,d[l].y=x;
    for(int i=1;i<=n;i++){
        while(l<=r&&i-d[l].x>=A)q[++qr]=d[l++];
        while(ql<=qr&&i-q[ql].x>=B)s[++sr]=q[ql++];
        int p=a[i];
        while(p){
            if(sl<=sr){
                if(s[sr].y>p)s[sr].y-=p,ret+=p*fB,p=0;
                else p-=s[sr].y,ret+=s[sr--].y*fB;
            }else if(ql<=qr){
                if(q[qr].y>p)q[qr].y-=p,ret+=p*fA,p=0;
                else p-=q[qr].y,ret+=q[qr--].y*fA;
            }else return INF;
        }d[++r].x=i,d[r].y=a[i];
    }return ret;
}
int Ternary_Search(int l,int r){
    while(1){
        if(r-l<=5){
            int fx=F(l);
            for(int i=l+1;i<=r;i++)fx=min(fx,F(i));
            return fx;
        }
        int x=l+(r-l)/3,y=l+2*(r-l)/3;
        int fx=F(x),fy=F(y);
        if(fx!=INF&&fx<=fy)r=y;
        else l=x;
    }return 0;
}
int main(){
    while(~scanf("%d%d%d%d%d%d",&n,&A,&B,&fA,&fB,&f)){
        if(A>B)swap(A,B),swap(fA,fB);
        if(fA<fB)fB=fA;
        int l=1,r=0;
        for(int i=1;i<=n;i++)scanf("%d",&a[i]),r+=a[i];
        printf("%d\n",Ternary_Search(l,r));
    }return 0;
}
时间: 2024-08-10 14:54:57

BZOJ 1229 [USACO2008 Nov]toy 玩具(三分+贪心)的相关文章

[BZOJ] 1618: [Usaco2008 Nov]Buying Hay 购买干草

1618: [Usaco2008 Nov]Buying Hay 购买干草 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1216  Solved: 633[Submit][Status][Discuss] Description 约翰的干草库存已经告罄,他打算为奶牛们采购H(1≤H≤50000)磅干草,他知道N(1≤N≤100)个干草公司,现在用1到 N给它们编号.第i个公司卖的干草包重量为Pi(1≤Pi≤5000)磅,需要的开销为Ci(l≤Ci≤5

BZOJ 1230: [Usaco2008 Nov]lites 开关灯( 线段树 )

线段树.. --------------------------------------------------------------------------------- #include<cstdio> #include<algorithm> #include<cstring> #include<iostream> #define rep( i , n ) for( int i = 0 ; i < n ; ++i ) #define clr( x

[BZOJ] 1620: [Usaco2008 Nov]Time Management 时间管理

1620: [Usaco2008 Nov]Time Management 时间管理 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 850  Solved: 539[Submit][Status][Discuss] Description Ever the maturing businessman, Farmer John realizes that he must manage his time effectively. He has N jobs

BZOJ 1618: [Usaco2008 Nov]Buying Hay 购买干草( dp )

无限背包dp.. 因为题目中说至少到 H 磅 , 我就直接把 H * 2 了.. -------------------------------------------------------------------------- #include<cstdio> #include<algorithm> #include<cstring> #include<iostream> #define rep( i , n ) for( int i = 0 ; i &

BZOJ 1620: [Usaco2008 Nov]Time Management 时间管理( 二分答案 )

二分一下答案就好了... ---------------------------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm> #include<cctype> #include<iostream> #define rep( i , n ) for( int i

BZOJ 1231: [Usaco2008 Nov]mixup2 混乱的奶牛( dp )

状压dp dp( x , S ) 表示最后一个是 x , 当前选的奶牛集合为 S , 则状态转移方程 : dp( x , S ) =  Σ dp( i , S - { i } )  ( i ∈ S , abs( h[ i ] - h[ x ] ) > k ) ------------------------------------------------------------------------------------------- #include<cstdio> #includ

BZOJ 1620 [Usaco2008 Nov]Time Management 时间管理:贪心

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1620 题意: 有n个工作,每一个工作完成需要花费的时间为tim[i],完成这项工作的截止日期为dead[i]. 问你在保证所有工作按时完成的前提下,最晚什么时候开始工作. (每天从时刻0开始算.如果无论如何都完成不了,输出-1) 题解: 贪心. 先将所有工作按dead从大到小排序. 当前开始工作的时间为start(初始为INF). 对于每个工作,start一定要满足两个条件: start

BZOJ 1618: [Usaco2008 Nov]Buying Hay

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1618 解:我看了半天觉得很像完全背包,可是又没法按套路来,于是翻了别人的题解,发现真是啊!!(一道神奇的背包) 我们发现也许最终的重量会超过H,但超过的部分绝对会小于maximum(p[i])(你总不会在已经买够了的情况下,再多买浪费钱吧),所以我们只要假设一个空间为H+maximum(p[i])的背包就可以了,然后套路一下,最后在(f[H]~f[maximum(p[i])])中找最优解

BZOJ 1231: [Usaco2008 Nov]mixup2 混乱的奶牛

Description 混乱的奶牛 [Don Piele, 2007] Farmer John的N(4 <= N <= 16)头奶牛中的每一头都有一个唯一的编号S_i (1 <= S_i <= 25,000). 奶牛为她们的编号感到骄傲, 所以每一头奶牛都把她的编号刻在一个金牌上, 并且把金牌挂在她们宽大的脖子上. 奶牛们对在挤奶的时候被排成一支"混乱"的队伍非常反感. 如果一个队伍里任意两头相邻的奶牛的编号相差超过K (1 <= K <= 3400