1. 程式人生 > 資訊 >平均海拔 4500 米,世界海拔最高高速公路通車

平均海拔 4500 米,世界海拔最高高速公路通車

題目大意

\(n\) 件商品,每一件商品價格為 \(P_i\) 個單位。

現在你手中共有 \(m\) 個單位的現金,以及 \(k\) 張優惠券。

你可以在購買某件商品時,使用至多一張優惠券,若如此做,該商品的價格會下降至 \(Q_i\)

請問你至多能購買多少件商品。

解題思路

考慮貪心,先不考慮有沒有優惠卷的情況肯定是從小到大買,這樣一定會買的最多的。

按照這個思想,每一次買的時候就找最小的。

有兩種情況:

  • 使用了優惠券之後獲得了一個最小值。
  • 沒有使用優惠券的最小值。

分別對 \(p\)\(q\) 進行排序。

每次找最小的。

還要將用來優惠券的那些東西按照 \(p_i − q_i\)

放到堆裡面,為以後撤銷優惠券使用。

這就是反悔貪心。

AC CODE

#include <cstdio>
#include <queue>
#include <algorithm>
using namespace std;
#define int long long
 
const int maxn = 1e6 + 5;
 
struct node
{
    int p, q;
    bool operator < (const node& rhs) const
    {
        return p - q > rhs.p - rhs.q;
    }
} a[maxn];
 
int n, k, ans;
long long m;
priority_queue<node> Q;
 
bool cmp(node a, node b)
{
    if(a.q != b.q)
        return a.q < b.q;
    return a.p < b.p;
}
 
bool CMP(node a, node b)
{
    return a.p < b.p;
}
 
signed main()
{
    scanf("%lld%lld%lld", &n, &k, &m);
    for (int i = 1; i <= n; i++)
        scanf("%lld%lld", &a[i].p, &a[i].q);
    sort(a + 1, a + n + 1, cmp);
    for (int i = 1; i <= k; i++)
    {
        m -= a[i].q;
        Q.push(a[i]);
        if (m < 0)
        {
            printf("%lld\n", i - 1);
            return 0;
        }
    }
    ans = k;
    sort(a + k + 1, a + n + 1, CMP);
    for (int i = k + 1; i <= n; i++)
    {
        int tp = Q.top().p, tq = Q.top().q;
        if (a[i].p - a[i].q > tp - tq && a[i].q + tp - tq <= m)
        {
            m -= (a[i].q + tp - tq);
            ans++, Q.pop(), Q.push(a[i]);
        }
        else if (a[i].p <= m)
            ans++, m -= a[i].p;
    }
    printf("%lld\n", ans);
    return 0;
}

本文來自部落格園,作者:蒟蒻orz,轉載請註明原文連結:https://www.cnblogs.com/orzz/p/15191687.html