• 【USACO12FEB】Cow Coupons G


    题目链接

    首先可以确定,在最优解中,$k$张优惠券一定会用光(除非带的钱实在太少)。

    于是一开始先选中$c$最小的前$k$只牛。可以证明,最优解中一定包含这些牛,然而优惠券却不一定全部用在它们身上。

    假设后来不买这其中的牛$i$,而是转而用优惠价买了这之外的牛$j$,发现$c_j>c_i$绝对是亏的。

    假设最后决定用原价买这其中的牛$i$,用腾出来的优惠券买了这之外的牛$j$,发现$p_i+c_j<c_i+p_j$是有可能存在的,此时$p_j-c_j>p_i-c_i$,也即牛$j$的折扣量比牛$i$的折扣量要大,这时候把优惠券用在牛$j$身上是更优的,那这样也是可行的。

    接下来继续买牛。如果要买一只牛$i$,可以按原价买,也可以取消已经选中的牛$j$的折扣来用优惠价买牛$i$,二者分别花费$p_i$和$c_i+p_j-c_j$。我们需要每次都选出最便宜的牛,这个用优先队列即可。

    用三个优先队列,分别提供当前$p_i,; c_i,; p_i-c_i$的最小的牛。注意别多次买同一只牛。

    代码(100分):

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<map>
    #include<set>
    #define IL inline
    #define RG register
    #define _1 first
    #define _2 second
    using namespace std;
    typedef long long LL;
    const int N=50000;
    const LL inf=2e9+1;
    
        int n,k;
        LL m;
        
    struct Cow{
        LL p,c;    int d;
    }a[N+3];
    
    struct cmp_p{IL bool operator()(Cow x,Cow y){return x.p>y.p;}};
    struct cmp_c{IL bool operator()(Cow x,Cow y){return x.c>y.c;}};
    struct cmp_pc{IL bool operator()(Cow x,Cow y){return x.p-x.c>y.p-y.c;}};
    
        priority_queue<Cow,vector<Cow>,cmp_p>qp;
        priority_queue<Cow,vector<Cow>,cmp_c>qc;
        priority_queue<Cow,vector<Cow>,cmp_pc>qpc;
        int ans;
        bool v[N+3];
    
    int main(){
        scanf("%d%d%lld",&n,&k,&m);
        for(int i=1;i<=n;i++){
            scanf("%lld%lld",&a[i].p,&a[i].c);
            a[i].d=i;
            qp.push(a[i]);    qc.push(a[i]);
            
        }
            
        ans=0;
        memset(v,0,sizeof v);
        for(int i=1;i<=k;i++){
            Cow x=qc.top();
            m-=x.c;
            v[x.d]=true;
            qpc.push(x);
            qc.pop();
            
            if(m<0){
                printf("%d",ans);    return 0;
            }
            ans++;
            
        }
        
        for(int i=k+1;i<=n;i++){
            while(v[qp.top().d])    qp.pop();
            while(v[qc.top().d])    qc.pop();
            Cow p=qp.top(),c=qc.top(),pc=qpc.top();
            
            if(p.p<c.c+pc.p-pc.c){
                m-=p.p;
                v[p.d]=true;
                qp.pop();
                
            }
            else {
                m-=c.c+pc.p-pc.c;
                v[c.d]=true;
                qpc.push(c);
                qc.pop();
                qpc.pop();
                
            }
            
            if(m<0)
                break;
            ans++;
            
        }
        
        printf("%d",ans);
        
        return 0;
    
    }
    View Code
  • 相关阅读:
    与DSP通信时,RD&WR信号
    4.2.1 Vector bit-select and part-select addressing
    数据校验
    数据结构 (树,图)
    ASOP编译说明
    os
    20180203-增与查
    yum安装MariaDB
    20180202之engine,URL,base,session
    列表
  • 原文地址:https://www.cnblogs.com/Hansue/p/12917995.html
Copyright © 2020-2023  润新知