zoukankan      html  css  js  c++  java
  • 【NOIP2017提高A组冲刺11.8】购物

    这个范围对DP不友好,和CF的一道C题非常像,贪心+后悔。

    先使用k个优惠券购买k个q最小的(钱不购买则退出),同时把这k个p[i]-q[i]放入小根堆,然后将剩下的n-k个按p升序排序,记小根堆堆顶为top,每次比较p[i]和q[i]+top(相当于反悔,用top的代价把之前的一个优惠券用到这里)

     感谢wwb的hack,虽然这题没出数据:当小根堆弹完之后就会出问题了,一个粗暴的解决方法是取堆顶之前判断是否空,若为空则返回极大值。

    #include<algorithm>
    #include<iostream>
    #include<cstdio>
    #include<queue>
    #define int long long
    using namespace std;
    
    inline int rd(){
        int ret=0,f=1;char c;
        while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
        while(isdigit(c))ret=ret*10+c-'0',c=getchar();
        return ret*f;
    }
    
    priority_queue<int> Q;
    
    inline void Push(int x){Q.push(-x);}
    inline int Top(){return Q.empty()?1<<29:-Q.top();}
    
    const int MAXN=50005;
    
    int n,num,m;
    int p[MAXN],q[MAXN];
    int vis[MAXN];
    int id[MAXN],iid[MAXN];
    int ans=0,cnt=0;
    bool cmp1(int x,int y){return q[x]<q[y];}
    bool cmp2(int x,int y){return p[x]<p[y];}
    
    
    signed main(){
        freopen("shopping.in","r",stdin);
        freopen("shopping.out","w",stdout);
        n=rd();num=rd();m=rd();
        for(int i=1;i<=n;i++){
            p[i]=rd();q[i]=rd();
            id[i]=iid[i]=i;
        }
        sort(id+1,id+1+n,cmp1);
        sort(iid+1,iid+1+n,cmp2);
        for(int i=1;i<=num;i++){
            if(ans+q[id[i]]>m) return cout<<cnt,0;
            ans+=q[id[i]];cnt++;
        }
        for(int i=1;i<=num;i++) Push(p[id[i]]-q[id[i]]),vis[id[i]]=1;
        for(int i=1;i<=n;i++){
            if(ans>m) return cout<<cnt-1,0;
            if(vis[iid[i]]) continue;
            if(q[iid[i]]+Top()>p[iid[i]]) {ans+=p[iid[i]],cnt++;continue;}
            ans+=q[iid[i]]+Top();cnt++;
            Q.pop();Push(p[iid[i]]-q[iid[i]]);
            
        }
        cout<<cnt-(ans>m);
        return 0;
    }

    本文来自博客园,作者:GhostCai,转载请注明原文链接:https://www.cnblogs.com/ghostcai/p/9439274.html

  • 相关阅读:
    linux整理
    C++ 11 多线程--线程管理
    VS2013 配置全局 VC++目录
    visual studio运行时库MT、MTd、MD、MDd的研究
    C++(vs)多线程调试 (转)
    VS工程和Qt工程转换
    Qt 读写XML文件
    win32开发中多字节(ANSI)和宽字符(UNICODE)字符串处理函数参考
    QMenu----QT鼠标右键弹出菜单
    C++ 单例模式析构函数的运用,析构函数的线程安全
  • 原文地址:https://www.cnblogs.com/ghostcai/p/9439274.html
Copyright © 2011-2022 走看看