2590: [Usaco2012 Feb]Cow Coupons
2590: [Usaco2012 Feb]Cow Coupons
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 306 Solved: 154
[Submit][Status][Discuss]
Description
Farmer John needs new cows! There are N cows for sale (1 <= N <= 50,000), and FJ has to spend no more than his budget of M units of money (1 <= M <= 10^14). Cow i costs P_i money (1 <= P_i <= 10^9), but FJ has K coupons (1 <= K <= N), and when he uses a coupon on cow i, the cow costs C_i instead (1 <= C_i <= P_i). FJ can only use one coupon per cow, of course. What is the maximum number of cows FJ can afford? PROBLEM NAME: coupons
FJ准备买一些新奶牛,市场上有N头奶牛(1<=N<=50000),第i头奶牛价格为Pi(1<=Pi<=10^9)。FJ有K张优惠券,使用优惠券购买第i头奶牛时价格会降为Ci(1<=Ci<=Pi),每头奶牛只能使用一次优惠券。FJ想知道花不超过M(1<=M<=10^14)的钱最多可以买多少奶牛?
Input
* Line 1: Three space-separated integers: N, K, and M.
* Lines 2..N+1: Line i+1 contains two integers: P_i and C_i.
Output
* Line 1: A single integer, the maximum number of cows FJ can afford.
Sample Input
3 2
2 2
8 1
4 3
Sample Output
OUTPUT DETAILS: FJ uses the coupon on cow 3 and buys cows 1, 2, and 3, for a total cost of 3 + 2 + 1 = 6.
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> #define LL long long using namespace std; const int M=55007; const LL inf=1e15; LL read(){ LL ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } LL m,n,k,v,cost; LL w[M],p[M],ans,sum; bool f[M]; struct node{ LL w,pos; bool operator < (const node& x)const {return x.w<w;} }; priority_queue<node>q1,q2,q3; int main() { n=read(); k=read(); m=read(); k=min(k,n); for(int i=1;i<=n;i++){ w[i]=read(); q1.push((node){w[i],i}); p[i]=read(); q2.push((node){p[i],i}); } for(ans=1;ans<=k;ans++){ node x=q2.top(); if(cost+x.w>m){printf("%lld\n",ans-1); return 0;} q2.pop(); f[x.pos]=1; cost+=x.w; q3.push((node){w[x.pos]-p[x.pos],x.pos}); }ans--; if(ans==n){printf("%lld\n",ans); return 0;} while(cost<=m&&ans<n){ node x=q3.top(),y=q2.top(),z=q1.top(); while(f[y.pos]&&!q2.empty()) q2.pop(),y=q2.top(); if(q2.empty()) y.w=inf; while(f[z.pos]&&!q1.empty()) q1.pop(),z=q1.top(); if(q1.empty()) z.w=inf; if(x.w+y.w<=z.w) f[y.pos]=1,q3.pop(),q2.pop(),q3.push((node){w[y.pos]-p[y.pos],y.pos}),cost+=x.w+y.w ; else q1.pop(),f[z.pos]=1,cost+=z.w; if(cost<=m) ans++; } printf("%lld\n",ans); return 0; }