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

    Description

    X 城的商场中,有着琳琅满目的各种商品。一日,小X 带着小Y 前来购物,小Y 一共看中了n件商品,每一件商品价格为Pi。小X 现在手中共有m个单位的现金,以及k 张优惠券。小X 可以在购买某件商品时,使用至多一张优惠券,若如此做,该商品的价格会下降至Qi。
    小X 希望尽可能多地满足小Y 的愿望,所以小X 想要知道他至多能购买多少件商品。
     

    Input

    第一行包含三个整数n,k,m,表示商品总数,小X 拥有的优惠券与现金总数。
    接下来n行每行包含两个整数Pi,Qi。

    Output

    共一行包含一个整数,表示小X 至多能购买的物品数。
     

    Sample Input

    4 1 7
    3 2
    2 2
    8 1
    4 3

    Sample Output

    3
    样例解释:一种最优的购买方式是购买1,2,3号物品,并用优惠券购买物品3,总共花费为3+2+1=6。
     
     
    做法:对Qi 和 Pi 排序, 先最小的K个Qi,然后将这K个Pi - Qi放进一个小根堆,每次比较Pi 和 Qi + 小根堆堆顶的值,更新答案和小根堆。一种具有撤销操作的贪心。
     
    代码如下:
     1 #include <cstdio>
     2 #include <iostream>
     3 #include <cstring>
     4 #include <queue>
     5 #include <algorithm>
     6 #define LL long long
     7 #define N 50007
     8 using namespace std;
     9 LL n, m, k, p[N], tot;
    10 struct arr
    11 {
    12     LL pi, qi;
    13 }q[N];
    14 priority_queue < LL, vector<LL>, greater<LL> > Q;
    15 
    16 LL cmp(arr x, arr y)
    17 {
    18     return x.qi < y.qi;
    19 }
    20 
    21 int main()
    22 {
    23     freopen("shopping.in", "r", stdin);
    24     freopen("shopping.out", "w", stdout);
    25     scanf("%lld%lld%lld", &n, &k, &m);
    26     for (int i = 1; i <= n; i++)
    27         scanf("%lld%lld", &q[i].pi, &q[i].qi);
    28     sort(q + 1, q + n + 1, cmp);
    29     LL ans = 0, site = 0;
    30     for (int i = 1; i <= k; i++)
    31     {
    32         if (m - q[i].qi >= 0)
    33         {
    34             m -= q[i].qi;
    35             ans++;
    36             Q.push(q[i].pi - q[i].qi);
    37             site = i;
    38         }
    39         else break;
    40     }
    41     if (site < k)
    42     {
    43         printf("%lld", ans);
    44         return 0;
    45     }
    46     for (int i = site + 1; i <= n; i++)
    47         p[i - site] = q[i].pi;
    48     tot = n - site;
    49     sort(p + 1, p + n - site + 1);
    50     LL j = 1;
    51     site++;
    52     while (m >= 0 && (j <= tot || site <= n))
    53     {
    54         LL now = Q.top();
    55         LL mi = min(p[j], q[site].qi + now);
    56         if (m - mi >= 0)
    57         {
    58             if (mi == p[j])
    59             {
    60                 m -= p[j];
    61                 j++;
    62                 ans++;
    63                 if (j > tot)    p[j] = 0x7f7f7f7f;
    64                 if (ans == n)    break;
    65             }
    66             else
    67             {
    68                 m -= q[site].qi + now;
    69                 ans++;
    70                 Q.pop();
    71                 Q.push(q[site].pi - q[site].qi);
    72                 site++;
    73             }
    74         }
    75         else break;
    76     }
    77     printf("%lld", ans);
    78 }
    View Code
  • 相关阅读:
    主外键 子查询
    正则表达式
    css3 文本效果
    css3 2d
    sql 基本操作
    插入 视频 音频 地图
    j-query j-query
    document
    js dom 操作
    js
  • 原文地址:https://www.cnblogs.com/traveller-ly/p/9439662.html
Copyright © 2011-2022 走看看