P3045 [USACO12FEB]Cow Coupons G
[USACO12FEB]Cow Coupons G - 洛谷
思路:我们首先根据c的大小排序,那么前k个如果可以买则一定买,如果不可以买说明钱一定不够了,因为后面的一定比前面的大;如果前k个能够都买了,那么我们在将考虑买后面的n-k个,我们需要维护三个队列,一个q1是前k个的p与c的差值,两外两个q2是n-k个的所有c,q3是n-k个的所有的p,三个都是小根堆,我们分别取出q2与q3的堆顶,如果我们买q2的话,说明我们现在要用一个优惠卷,但是我们前面买k个的时候已经用完了,如果继续使用就需要补上以前买过的牛的差价,所以它需要加上的是q2.top+q1.top,而q3的话就是直接按照原价买,所以就是分情况讨论哪一个更小用哪一个,同时需要更新q1,q2,q3,还要把用过的打上标记,防止在q2种使用了,在q3中再使用
#include<iostream>
#include<cstring>
#include<vector>
#include<map>
#include<queue>
#include<unordered_map>
#include<cmath>
#include<cstdio>
#include<algorithm>
#include<set>
#include<cstdlib>
#include<stack>
#include<ctime>
#define forin(i,a,n) for(int i=a;i<=n;i++)
#define forni(i,n,a) for(int i=n;i>=a;i--)
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> PII;
typedef pair<pair<int,int>,int> PIII;
const double eps=1e-7;
const int N=5e4+7,M=2*N , INF=0x3f3f3f3f,mod=1e9+7;
inline ll read() {ll x=0,f=1;char c=getchar();while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9') {x=(ll)x*10+c-'0';c=getchar();} return x*f;}
void stin() {freopen("in_put.txt","r",stdin);freopen("my_out_put.txt","w",stdout);}
void hack() {printf("\n----------------------------------\n");}
bool cmp(int a,int b) {return a>b;}
int hackT;
template<typename T> T gcd(T a,T b) {return b==0?a:gcd(b,a%b);}
template<typename T> T lcm(T a,T b) {return a*b/gcd(a,b);}
int T;
ll n,m,k;
bool st[N];
struct Node{
int p,c;
bool operator < (const Node &k) const {
return c<k.c;
}
};
Node w[N];
void solve() {
n=read(),k=read(),m=read();
for(int i=1;i<=n;i++) w[i].p=read(),w[i].c=read();
sort(w+1,w+1+n);
priority_queue<int,vector<int>,greater<int> > q1;
priority_queue<PII,vector<PII>,greater<PII> > q2,q3;
int ans=0;
for(int i=1;i<=k;i++) {
if(m-w[i].c>=0) {
m-=w[i].c;
ans++;
}
q1.push(w[i].p-w[i].c);
}
for(int i=k+1;i<=n;i++) {
q2.push({w[i].c,i});
q3.push({w[i].p,i});
}
for(int i=k+1;i<=n;i++) {
auto a=q2.top();
while(q2.size()&&st[a.second]) {
q2.pop();
a=q2.top();
}
auto b=q3.top();
while(q3.size()&&st[b.second]) {
q3.pop();
b=q3.top();
}
int x=a.first+q1.top();
int y=b.first;
if(x>y) {
if(m-y>=0) {
m-=y;
ans++;
st[b.second]=true;
q3.pop();
}else break;
}else {
if(m-x>=0) {
m-=x;
ans++;
q2.pop();
q1.pop();
q1.push(w[a.second].p-w[a.second].c);
st[a.second]=true;
}else break;
}
}
printf("%d\n",ans);
}
int main() {
// init();
// stin();
// scanf("%d",&T);
T=1;
while(T--) hackT++,solve();
return 0;
}