zoukankan      html  css  js  c++  java
  • BZOJ 1229: [USACO2008 Nov]toy 玩具

    BZOJ 1229: [USACO2008 Nov]toy 玩具

    标签(空格分隔): OI-BZOJ OI-三分 OI-双端队列 OI-贪心


    Time Limit: 10 Sec
    Memory Limit: 162 MB


    Description

    玩具 [Chen Hu, 2006] Bessie的生日快到了, 她希望用D (1 <= D <= 100,000; 70%的测试数据都满足 1 <= D <= 500)天来庆祝. 奶牛们的注意力不会太集中, 因此Bessie想通过提供玩具的方式来使它们高兴. 她已经计算出了第i天需要的玩具数T_i (1 <= T_i <= 50). Bessie的幼儿园提供了许多服务给它们的奶牛程序员们, 包括一个每天以Tc (1 <= Tc <= 60)美元卖出商品的玩具店. Bessie想尽可能的节省钱, 但是Farmer John担心没有经过消毒的玩具会带来传染病(玩具店卖出的玩具是经过消毒的). 有两种消毒的方式. 第1种方式需要收费C1美元, 需要N1个晚上的时间; 第2种方式需要收费 C2美元, 需要N2个晚上的时间(1 <= N1 <= D; 1 <= N2 <= D; 1 <= C1 <= 60; 1 <= C2 <= 60). Bessie在party结束之后把她的玩具带去消毒. 如果消毒只需要一天, 那么第二天就可以拿到; 如果还需要一天, 那么第三天才可以拿到. 作为一个受过教育的奶牛, Bessie已经了解到节约的意义. 帮助她找到提供玩具的最便宜的方法.

    Input

    • 第 1 行: 六个用空格隔开的整数 D, N1, N2, C1, C2, Tc

    • 第 2..D+1 行: 第 i+1 行包含一个整数: T_i

    Output

    第 1 行: 提供玩具所需要的最小费用.

    Sample Input

    4 1 2 2 1 3

    8

    2

    1

    6

    输入解释:

    Bessie想开4天的party, 第1天需要8个玩具, 第2天需要2个玩具, 第3天需要1个玩具,

    第4天需要6个玩具. 第一种方式需要$2, 用时1天; 第二种方式需要$1, 用时2天. 买

    一个玩具需要$3.

    Sample Output

    35

    输出解释:

    第 1 天 买8个玩具, 花去$24; 送2个玩具去快洗, 6个慢洗.

    第 2 天 取回2个快洗的玩具, 花去$4. 送1个玩具去慢洗.

    第 3 天 取回6个慢洗的玩具, 花去$6.

    第 4 天 取回所有的玩具(与现有的加在一起正好6个), 花去$1. 这样就用了最少的钱.


    Solution####

    如果D比较小,这题就是经典的费用流模型
    (餐巾计划问题,每天建2个点(x_i),(y_i)分别表示未洗好和洗好,S向(x_i)连容量为(t_i),费用为0的边,表示当天使用后的餐巾加入未洗。(y_i)向T连费用为(t_i)的边,表示使用的餐巾。S想(y_i)连费用为Tc的边表示购买。 (x_i)(y_{i+n1})连费用为(c_1)的边,表示第一种洗法,(x_i)(y_{i+n2})连费用为(c_2)的边,表示第二种洗法。(x_i)(x_{i+1})连费用为0的边,表示当天不洗)。但是D很大,这个做法明显会超时。重新来看费用流,单位费用随流量的增加而减少。也就是费用是个凸函数!而流量恰好是玩具个数。
    三分玩具总数,贪心求出费用。
    贪心:首先确定了玩具总数,付出sum*Tc的代价。设(n_1<n_2) (c_1>c_2)。1表示快洗,2表示慢洗。按时间从早到晚处理,贪心维护一个关于使用时间有序的双端队列。当天的玩具优先用购买却未曾使用的,代价为0;其次使用慢洗的(即满足(T_i+n_1<=T_{now})),代价为(c_1);最后是最近时间快洗的(即满足(T_i+n_2<=T_{now})的最大(T_i)),代价为(c_2);


    Code####

    #include<bits/stdc++.h>
    using namespace std;
    #define PA pair<int,int>
    int n,n1,n2,c1,c2,tc;
    int t[100005],sumt;
    PA MP(int a,int b){PA c;c.first=a,c.second=b;return c;}
    deque<PA>q;
    int cos(int sum)
    {
    	q.clear();
    	int ans=sum*(tc-c2);
    	q.push_front(MP(-n2,sum));
    	for(int i=1;i<=n;i++)
    	   {
    	    if(i-n1>=1)
    	   	   q.push_front(MP(i-n1,t[i-n1]));
    	    for(int T=t[i];T;)
    	       {if(q.empty())return 1e9;
    	        PA x=q.back();
    	       	if(x.first+n2<=i&&c1>c2)
    			  {int s=min(T,x.second);
    			   T-=s;x.second-=s;
    			   ans+=s*c2;
    			   q.pop_back();
    			   if(x.second)q.push_back(x);
    			  }
    	       	else
    	       	  {x=q.front();
    	       	   int s=min(T,x.second);
    			   T-=s;x.second-=s;
    			   ans+=s*c1;
    			   q.pop_front();
    			   if(x.second)q.push_front(x);
    			  }
    		   }
       	   }
       	return ans;
    }
    int sf()
    {
    	int l=1,r=sumt;
    	while(l+20<r)
    	  {int mid1=(l*2+r)/3,mid2=(l+r*2)/3;
    	   int v1=cos(mid1),v2=cos(mid2);
    	   if(v1<v2)r=mid2;
    	   else l=mid1;
    	  }
    	int ans=1e9;
    	for(int i=l;i<=r;i++)
    	    ans=min(ans,cos(i));
    	return ans;
    }
    int main()
    {
    	scanf("%d%d%d%d%d%d",&n,&n1,&n2,&c1,&c2,&tc);
    	if(n1>n2)swap(n1,n2),swap(c1,c2);
    	for(int i=1;i<=n;i++)
    	    scanf("%d",&t[i]),sumt+=t[i];
    	printf("%d
    ",sf());
    	return 0;
    }
    
    
  • 相关阅读:
    J2EE规范标准
    怎样用Google APIs和Google的应用系统进行集成(4)----获得Access Token以通过一些Google APIs的OAuth2认证
    [BestCoder Round #3] hdu 4908 BestCoder Sequence (计数)
    大数据存储之分布式文件系统(一)
    List与array的相互转换
    TRIZ系列-创新原理-31-多孔材料原理
    关于app.FragmentManager和v4包的FragmentPagerAdapter冲突
    POJ 1163 The Triangle
    ChinaVis2015 第一天会议
    JSON初入门
  • 原文地址:https://www.cnblogs.com/wuyuhan/p/5240253.html
Copyright © 2011-2022 走看看