Kevin逛超市 2 (困难版本)

Kevin逛超市 2 (困难版本)

堆反悔贪心

#include <bits/stdc++.h>
using namespace std;

void solve() {
    int n, a, b;
    long long x, y;
    cin >> n >> a >> b >> x >> y;

    vector<long double> p(n);
    long double total = 0;

    for(int i = 0; i < n; i ++) {
        cin >> p[i];
        total += p[i];
    }

    sort(p.begin(), p.end(), greater<long double>());
    long double alpha = (100.0L - x) / 100.0L; // 折扣比例
    vector<int> state(n, 0); // state: 0 未使用, 1 使用折扣券, 2 使用立减券

    priority_queue<pair<long double, int>> pq;

    long double save = 0;
    // 初始:价格最高的 a 个商品使用折扣券
    int u = a; // 指向第一个未使用商品
    for(int i = 0; i < a; i ++) {
        state[i] = 1;
        save += alpha * p[i];

        long double r = min(p[i], (long double)y) - alpha * p[i];
        pq.push({r, i});
    }

    for(int used = 0; used < b; used ++) {
        // 清除堆中已经无效的元素
        while(!pq.empty() && state[pq.top().second] != 1) pq.pop();

        bool hasDiscount = !pq.empty();
        bool hasUnused = (u < n);

        long double incA = -1e100L; // 直接立减未使用最高价
        long double incB = -1e100L; // 替换一张折扣券,并把折扣券给未使用最高价

        if(hasUnused) incA = min(p[u], (long double)y);
        if(hasDiscount) {
            long double maxR = pq.top().first;
            if(hasUnused) incB = maxR + alpha * p[u];
            else incB = maxR;
            
        }
        long double inc = max(incA, incB);
        if(inc <= 0) break;
        if(incA >= incB) {
            // 直接给未使用最高价商品使用立减券
            save += incA;
            state[u] = 2;
            u ++;
        }
        else {
            // 替换一张折扣券
            auto [rval, id] = pq.top(); pq.pop();
            save += incB;
            state[id] = 2;

            if(hasUnused) {// 空出的折扣券给未使用最高价商品
                state[u] = 1;
                long double newR = min(p[u], (long double)y) - alpha * p[u];
                pq.push({newR, u});
                u ++;
            }
        }
    }

    long double ans = total - save;

    cout << fixed << setprecision(12) << (double)ans << '\n';
}

int main() {
    ios::sync_with_stdio(false); cin.tie(nullptr);
    int _; cin >> _;
    while(_--) solve();
    return 0;
}
posted @ 2026-11-03 21:49  thenrify  阅读(3)  评论(0)    收藏  举报