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

BOZJ-2590 优惠券

时间:2019-07-21 20:12:56      阅读:121      评论:0      收藏:0      [点我收藏+]

标签:cin   操作   折扣   输入   main   代码   cpp   dea   排序   

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;
}

BOZJ-2590 优惠券

标签:cin   操作   折扣   输入   main   代码   cpp   dea   排序   

原文地址:https://www.cnblogs.com/jeffersonqin/p/11222422.html

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