P3045 [USACO12FEB] Cow Coupons G (用堆實現反悔貪心)

medicos發表於2024-10-20

題解


題目連結

P3045 [USACO12FEB] Cow Coupons G

解題思路

反悔貪心
大體思路即為: 將所有 \(p_i\)\(c_i\) 分別存入兩個小根堆中,每次取出下標未使用過的堆頂元素 \(p_i\)\(c_j\),並變成實際的應增加費用 \(p_i\)\(c_j + \Delta k\) (最小的 \(p_k - c_k\)) 進行比較,決定選擇 \(i\) 還是 \(j\) . 具體的思路與證明可以看Luogu題解, 裡面非常詳細與全面.

重點程式碼部分就是

if (tc + delta.top() > tp) {    //相當於將 對i使用優惠卷實際上應該增加的費用 和 不對j使用優惠卷應該增加的費用 作比較
            m -= tp;
            P.pop();
            vis[i] = 1;
        }
        else {
            m -= tc + delta.top();
            delta.pop();
            C.pop();
            vis[j] = 1;
            delta.push(p[j] - c[j]);
        }

這裡Luogu的大部分題解寫的都是 移項後的 \(delta.top() > tp - tc\), 困擾了我非常久:為什麼tp和tc明明對應的下標不一定一樣,卻可以直接相減.

時間複雜度與空間複雜度分析

由於堆的使用, 兩個最大大小為n和一個大小為k的堆,時間與空間複雜度均為 \(O(nlogn)\) 左右.

完整程式碼

#include <bits/stdc++.h>

#define int long long

using namespace std;

using PII = pair<int, int>;

signed main() {
    ios::sync_with_stdio(0), cin.tie(0);

    int n, k, m;
    cin >> n >> k >> m;

    priority_queue<PII, vector<PII>, greater<>> P, C;
    priority_queue<int, vector<int>, greater<>> delta;

    vector<int> p(n + 1), c(n + 1), vis(n + 1);
    for (int i = 1; i <= n; ++i) {
        cin >> p[i] >> c[i];
        P.push({p[i], i});
        C.push({c[i], i});
    }
    for (int i = 1; i <= k; ++i) delta.push(0);  //相當於給了k次無腦使用優惠卷的機會
    int ans = 0;
    while (P.size()) {
        auto [tp, i] = P.top();
        auto [tc, j] = C.top();
        if (vis[i]) {
            P.pop();
            continue;
        }
        if (vis[j]) {
            C.pop();
            continue;
        }
        if (tc + delta.top() > tp) {    //相當於將 對i使用優惠卷實際上應該增加的費用 和 不對j使用優惠卷應該增加的費用 作比較
            m -= tp;
            P.pop();
            vis[i] = 1;
        }
        else {
            m -= tc + delta.top();
            delta.pop();
            C.pop();
            vis[j] = 1;
            delta.push(p[j] - c[j]);
        }
        if (m >= 0) ans++;
        else break;
    }
    cout << ans << "\n";

    return 0;
}

AC提交記錄

(https://www.luogu.com.cn/record/176544896)
image

相關文章