码迷,mamicode.com
首页 > 其他好文 > 详细

2018.8.7提高B组模拟考试

时间:2018-08-07 21:30:17      阅读:139      评论:0      收藏:0      [点我收藏+]

标签:stream   tar   tps   can   小根堆   div   names   inf   empty   

T1 题意简述:jzoj5461

   解题思路:贪心。

             考虑先用完k张优惠券,只需将商品按优惠价排序,依次判断钱是否足够,若是则ans++,否则直接退

             出循环并输出ans即可。

             k张优惠券用完后若钱还未用完,则考虑用前面商品的优惠券买后面的商品。注意要把未买的商品按

             原价重新排序。只需把用了优惠券的商品的原价与优惠价之差价放进一个小根堆,每次判断:此商品

             原价是否小于堆顶商品差价+此商品优惠价。若是则直接用原价买即可,否则用堆顶商品差价+此商品

             优惠价买即可。注意有0张优惠券的情况,因此要特判队列是否为空,若是则直接用原价买即可。

             由于本蒟蒻及ErkkiErkko大佬均认为把商品按原价重新排序的方法有误,故欢迎各位大佬前来Hack。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<queue>
#include<vector>
#define INF 0x3f3f3f3f
#define ll long long
using namespace std;
ll n,k,m,ans;
priority_queue<ll,vector<ll>,greater<ll> > que;
struct uio{
    ll val,fre;
}war[50001];
bool cmp(uio x,uio y)
{
    if(x.fre==y.fre)
        return x.val<y.val;
    return x.fre<y.fre;
}
bool cmp1(uio x,uio y)
{
    return x.val<y.val;
}
int main()
{
    freopen("shopping.in","r",stdin);
    freopen("shopping.out","w",stdout);
    scanf("%lld%lld%lld",&n,&k,&m);
    for(ll i=1;i<=n;i++)
        scanf("%lld%lld",&war[i].val,&war[i].fre);
    sort(war+1,war+1+n,cmp);
    for(ll i=1;i<=k;i++)
    {
        que.push(war[i].val-war[i].fre);
        if(m>=war[i].fre) m-=war[i].fre,ans++;
    }
    sort(war+1+k,war+1+n,cmp1);
    for(ll i=k+1;i<=n;i++)
    {
        if(m>=war[i].val&&(que.empty()||que.top()>war[i].val-war[i].fre)) m-=war[i].val,ans++;
        else if(!que.empty()&&m>=war[i].fre+que.top()) m-=war[i].fre+que.top(),ans++,que.pop(),que.push(war[i].val-war[i].fre);
    }
    printf("%lld\n",ans);
    return 0;
}

 


 

 

T2 题意简述:jzoj5455

   解题思路:

2018.8.7提高B组模拟考试

标签:stream   tar   tps   can   小根堆   div   names   inf   empty   

原文地址:https://www.cnblogs.com/water-radish/p/9439386.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!