• BOZJ-2590 优惠券


    BOZJ-2590 优惠券


    题目:

    约翰需要买更多的奶牛!交易市场上有n头奶牛等待出售,第ii头奶牛的原价是(p_i)元,使用优惠券之后,折扣价为(c_i)元。约翰有m元钱和k张优惠券。请问约翰最多能买多少头奶牛回家?每头牛只能用一张优惠券,每张优惠券的效果都一样。

    输入格式

    第一行:三个整数nkm第二行到第n+1行:第i+1行有两个整数(p_i)(c_i)

    输出格式

    单个整数:表示约翰最多能买几头牛

    数据范围

    (1 ≤ k ≤ n ≤ 50000,~1≤m≤10^{14}, 1≤c_i≤p_i≤10^9)


    题解:

    首先可以根据(c_i)进行排序,可以发现一个问题:现在若有(k)张优惠券,那么将前(k)头用优惠券最便宜的牛全部买下。对于后面的牛,每一次操作,找出用普通价格买最便宜的牛,在没买的牛当中用优惠券买的最便宜的牛,在买了的牛当中,优惠券与普通价格只差(优惠券的赎金)最便宜的牛。

    比较两个值:

    1. 最小赎金 + 最小优惠券价格
    2. 最小普通价格

    所以只需要维护3个堆:

    1. 没买的用普通价格的堆
    2. 没买的用优惠券价格的堆
    3. 买了的赎金

    代码:

    #include <iostream>
    #include <queue>
    #include <algorithm>
    
    using namespace std;
    typedef long long ll;
    
    const int maxn = 50005;
    ll n, k, m;
    pair<ll, ll> cost[maxn];
    priority_queue< pair<ll, ll> > use_c_heap, not_use_c_heap, not_use_price_heap;
    bool dead_price[maxn], dead_c[maxn];
    
    void del_wait_coupen(ll a) {
        dead_c[a] = true;
    }
    void del_wait_price(ll a) {
        dead_price[a] = true;
    }
    
    pair<ll, ll> top_wait_price() {
        pair<ll, ll> a = not_use_price_heap.top();
        while (dead_price[a.second]) {
            not_use_price_heap.pop();
            a = (not_use_price_heap.empty() ? (pair<ll, ll>) make_pair(0, 0) : not_use_price_heap.top());
        }
        return a;
    }
    
    pair<ll, ll> top_wait_coupen() {
        pair<ll, ll> a = not_use_c_heap.top();
        while (dead_c[a.second]) {
            not_use_c_heap.pop();
            a = (not_use_c_heap.empty() ? (pair<ll, ll>) make_pair(0, 0) : not_use_c_heap.top());
        }
        return a;
    }
    
    int main() {
        ll ans = 0;
        cin >> n >> k >> m;
        for (int i = 1; i <= n; i ++) {
            cin >> cost[i].second >> cost[i].first;
        }
    
        sort(cost + 1, cost + 1 + n);
        for (int i = 1; i <= k; i ++) {
            if (m >= cost[i].first) {
                use_c_heap.push(make_pair(-1 * (cost[i].second - cost[i].first), i));
                m -= cost[i].first;
                ans ++;
            }
        }
        // 即便用优惠券,也买不起任意一头牛
        if (ans == 0) {
            cout << 0 << endl; return 0;
        }
        for (int i = k + 1; i <= n; i ++) {
            not_use_c_heap.push(make_pair(-1 * cost[i].first, i));
            not_use_price_heap.push(make_pair(-1 * cost[i].second, i));
        }
        for (int i = k + 1; i <= n; i ++) {
            pair<ll, ll> wait_price = top_wait_price();
            pair<ll, ll> wait_c = top_wait_coupen();
            pair<ll, ll> use_cost_price = use_c_heap.top();
            if ((-1 * wait_price.first) < ((-1 * wait_c.first) + (-1 * use_cost_price.first)) && m >= (-1 * wait_price.first)) {
                not_use_price_heap.pop();
                del_wait_coupen(wait_price.second);
                ans ++;
                m -= (-1 * wait_price.first);
            } else {
                if (m >= -1 * (wait_c.first + use_cost_price.first)) {
                    use_c_heap.pop();
                    del_wait_price(wait_c.second);
                    use_c_heap.push(make_pair(-1 * (cost[wait_c.second].second - (-1) * wait_c.first), wait_c.second));
                    ans ++;
                    m -= (-1 * (wait_c.first + use_cost_price.first));
                }
            }
        }
        cout << ans << endl;
        return 0;
    }
    
  • 相关阅读:
    BZOJ1691: [Usaco2007 Dec]挑剔的美食家
    BZOJ1584: [Usaco2009 Mar]Cleaning Up 打扫卫生
    BZOJ3057: 圣主的考验
    BZOJ1770: [Usaco2009 Nov]lights 燈
    1710: [Usaco2007 Open]Cheappal 廉价回文
    「Poetize7」电话线路
    「Poetize6」Candle
    「Poetize5」水叮当的舞步
    解题:CF983A Finite or not
    解题:POI 2013 Triumphal arch
  • 原文地址:https://www.cnblogs.com/jeffersonqin/p/11222422.html
Copyright © 2020-2023  润新知