题解:Luogu_P3045 [USACO12FEB] Cow Coupons G
题解:Luogu_P3045 [USACO12FEB] Cow Coupons G
Solution
首先有个最初的的想法,将所有牛不用优惠券的价格扔进一个小根堆里,用优惠券的价格扔进一个小根堆,每次比较两个堆顶的价格,选花钱最少的。
看组数据:
3 2 6
5 1
3 1
4 2
按照我们的策略,会选 1、2 号牛,实际如果选 1、3 号牛使用优惠券,剩下的钱可以买下 2 号牛。
问题出在哪里?我们没能正确分配对哪头牛使用优惠券,不过好在这种贪心方法虽然不能保证买到的牛最多,但能保证选到的牛最后都会被买到。(自己讨论一下哪些情况会被选到,发现扔掉都是不优的)
本质的问题出在我们在分配优惠券时,没能考虑每张优惠券能省多少,导致有些优惠券省的钱太少了,买同样的牛,将一些优惠券分配给 \(p_i-c_i\) 更大的牛总价钱会更少。
于是我们再弄一个小根堆,用来存 \(k\) 张优惠券的省钱情况,如果有牛可以更省就把优惠券给新的牛用。
Code
计算细节看代码
//P3045
#include <iostream>
#include <cstdio>
#include <map>
#include <queue>
#define lld long long
#define pii pair <int, int>
using namespace std;
inline lld read()
{
lld val = 0;
bool si = 0;
char ch = getchar();
for (; !isdigit(ch); ch = getchar())
si ^= ch == '-';
for (; isdigit(ch); ch = getchar())
val = (val << 3) + (val << 1) + (ch ^ 48);
return si ? - val : val;
}
const int N = 50005;
int n, k, p[N], c[N], ans;
lld m;
bool vis[N];
priority_queue <pii, vector <pii>, greater <pii> > heap, heac;
priority_queue <int, vector <int>, greater <int> > cost;
int main()
{
n = read(), k = read(), m = read();
for (int i = 1; i <= n; i ++)
{
heap.push(make_pair(p[i] = read(), i));
heac.push(make_pair(c[i] = read(), i));
}
for (int i = 1; i <= k; i ++)
cost.push(0);
while (!heap.empty() && !heac.empty())
{
pii nowp = heap.top();
if (vis[nowp.second])
{
heap.pop();
continue;
}
pii nowc = heac.top();
if (vis[nowc.second])
{
heac.pop();
continue;
}
if (nowp.first <= nowc.first + cost.top())
{
m -= nowp.first;
vis[nowp.second] = 1;
heap.pop();
}
else
{
m -= nowc.first + cost.top();
vis[nowc.second] = 1;
heac.pop();
cost.pop();
cost.push(p[nowc.second] - c[nowc.second]);
}
if (m < 0) break;
ans ++;
}
printf("%d\n", ans);
return 0;
}

浙公网安备 33010602011771号