卧薪尝胆,厚积薄发。
USACO2012FEB Cow Coupons
Date: Sat Sep 08 17:06:29 CST 2018
In Category:
NoCategory
Description:
有
$N$
个商品,第
$i$
个商品价格为
$P_i$
。有
$K$
张优惠券,使用优惠券购买第
$i$
个商品价格会降为
$C_i$
。求花不超过
$M$
的钱最多可以买多少奶牛?
$1\le n \le 50000$
Solution:
先用优惠券买
$C$
前
$K$
小的牛,在最小堆中加入
$P-C$
代表可以用这么多价值获得一张优惠券,剩下的牛按
$P$
升序排序,如果
$P-C>q.top()$
,即如果把它用优惠券买能省下更多的钱,那就取出堆顶并把
$P-C$
放到堆里,如果不能就用原价买,因为用优惠券会亏,不断重复直到超过
$m$
。
Code:
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<queue>
#include<cstring>
using namespace std;
int n,k;
#define MAXN 50010
long long m;
struct obj
{
int p,c;
}s[MAXN];
bool cmp_p_from_low_to_high(obj a,obj b){return a.p < b.p;}
bool cmp_c_from_low_to_high(obj a,obj b){return a.c < b.c;}
priority_queue<int,vector<int>,greater<int> > q;
int main()
{
scanf("%d%d%lld",&n,&k,&m);
for(int i = 1;i <= n;++i)
scanf("%d%d",&s[i].p,&s[i].c);
sort(s + 1,s + 1 + n,cmp_c_from_low_to_high);
long long sum = 0;
for(int i = 1;i <= k;++i)
{
if(sum + s[i].c > m)
{
cout << i - 1 << endl;
return 0;
}
sum += s[i].c;
q.push(s[i].p - s[i].c);
}
if(k == n)
{
cout << n << endl;
return 0;
}
sort(s + k + 1,s + 1 + n,cmp_p_from_low_to_high);
for(int i = k + 1;i <= n;++i)
{
if(s[i].p - s[i].c > q.top())
{
sum += q.top();
q.pop();
sum += s[i].c;
q.push(s[i].p - s[i].c);
}
else
{
sum += s[i].p;
}
if(sum > m)
{
cout << i - 1 << endl;
return 0;
}
}
cout << n << endl;
return 0;
}
In tag:
算法-贪心
Copyright © 2020
wjh15101051
ღゝ◡╹)ノ♡