zoukankan      html  css  js  c++  java
  • BZOJ1229 USACO2008 Nov toy 玩具 【三分+贪心】*

    BZOJ1229 USACO2008 Nov toy 玩具


    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. 这样就用了最少的钱.


    我们可以考虑当购买的玩具确定的时候会发生什么
    很显然除了一些玩具数太少的情况其他的情况都是可行的
    然后我也不知道为什么花费是单峰的
    网上好像也没什么大佬给出了证明
    可以意会一下,当购买的玩具增加,购买的花费呈一次函数,然后消毒的花费应该是递减的,然后好像可以想当然的认为这是个单峰函数
    然后就三分+check
    在check的时候可以维护一下当前可以用第一种方案消毒的,可以第二种方案消毒的然后进行贪心,至于不合法的状态直接判过去就好了


    #include<bits/stdc++.h>
    using namespace std;
    #define N 100010
    #define INF 0x3f3f3f3f
    #define pi pair<int,int>
    int n,n1,n2,c1,c2,tc;
    int d[N];
    deque<pi> t,p,q;
    int calc(int x){
        t.clear();
        p.clear();
        q.clear();
        int sum=(tc-c2)*x;
        p.push_back(make_pair(0,x));
        for(int i=1;i<=n;++i){
            while(!t.empty()&&i-t.front().first>=n1)q.push_back(t.front()),t.pop_front();
            while(!q.empty()&&i-q.front().first>=n2)p.push_back(q.front()),q.pop_front();
            int now=d[i];
            while(now){
                if(!p.empty()){
                    if(p.back().second>now){
                        p.back().second-=now;
                        sum+=now*c2;now=0;
                        break;
                    }
                    now-=p.back().second;
                    sum+=p.back().second*c2;
                    p.pop_back();
                    continue;
                }
                if(!q.empty()){
                    if(q.back().second>now){
                        q.back().second-=now;
                        sum+=now*c1;now=0;
                        break;
                    }
                    now-=q.back().second;
                    sum+=q.back().second*c1;
                    q.pop_back();
                    continue;
                }
                return INF;
            }
            t.push_back(make_pair(i,d[i]));
        }
        return sum;
    }
    int main(){
        freopen("1229.in","r",stdin);
        scanf("%d%d%d%d%d%d",&n,&n1,&n2,&c1,&c2,&tc);
        if(n1>n2)swap(c1,c2),swap(n1,n2);
        int sum=0;
        for(int i=1;i<=n;i++)scanf("%d",&d[i]),sum+=d[i];
        int l=1,r=sum;
        while(l+10<r){
            int tmp=(r-l)/3;
            int ll=l+tmp,rr=r-tmp;
            if(calc(ll)<calc(rr))r=rr;
            else l=ll;
        }
        int ans=INF;
        for(int i=l;i<=r;i++)ans=min(ans,calc(i));
        printf("%d",ans);
        return 0;
    }
    
  • 相关阅读:
    再谈每周工作不要超过 40 小时
    前苹果雇员潜入总部 只为完成自己的项目
    C语言解析pcap文件得到HTTP信息实例(原创,附源码)
    Android 2.1 源码结构分析
    linux 获取当前日期与时间
    谷歌史上十大优秀产品榜:Android傲娇上位
    在eclipse中查看android SDK的源代码
    网络开发必备的HTTP协议知识
    Linux TCP/IP协议栈源码阅读笔记
    浅析UPnP协议
  • 原文地址:https://www.cnblogs.com/dream-maker-yk/p/9676308.html
Copyright © 2011-2022 走看看