bzoj2590[Usaco2012 Feb]Cow Coupons*
bzoj2590[Usaco2012 Feb]Cow Coupons
题意:
市场上有N头奶牛,第i头奶牛价格为Pi。FJ有K张优惠券,使用优惠券购买第i头奶牛时价格会降为Ci,每头奶牛只能使用一次优惠券。FJ想知道花不超过M的钱最多可以买多少奶牛。n≤50000,m≤10^14。
题解:
先按ci升序排序,把前k头买下来(如果可以的话)接着把剩下的牛按pi升序排序:如果当前奶牛优惠价与原价差值比k头奶牛中最大的一头大,则花那一头优惠价与原价差值把优惠券“赎”回来,并用优惠价买当前奶牛;否则直接以原价买当前奶牛。
代码:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <queue> 5 #define inc(i,j,k) for(int i=j;i<=k;i++) 6 #define maxn 50010 7 #define INF 0x3fffffff 8 #define ll long long 9 using namespace std; 10 11 inline ll read(){ 12 char ch=getchar(); ll f=1,x=0; 13 while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();} 14 while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar(); 15 return f*x; 16 } 17 struct nd{int p,c;}nds[maxn]; int n,k; ll m,sum; priority_queue<int,vector<int>,greater<int> >q; 18 bool cmp1(nd a,nd b){return a.c<b.c;} 19 bool cmp2(nd a,nd b){return a.p<b.p;} 20 int main(){ 21 n=read(); k=read(); m=read(); inc(i,1,n)nds[i].p=read(),nds[i].c=read(); sort(nds+1,nds+1+n,cmp1); 22 inc(i,1,k){ 23 sum+=nds[i].c; if(sum>m){printf("%d",i-1); goto end;} 24 if(i==n){printf("%d",n); goto end;} q.push(nds[i].p-nds[i].c); 25 } 26 sort(nds+1+k,nds+n+1,cmp2); 27 inc(i,k+1,n){ 28 int t=q.empty()?INF:q.top(); 29 if(nds[i].p-nds[i].c>t){sum+=t; q.pop(); sum+=nds[i].c; q.push(nds[i].p-nds[i].c);}else sum+=nds[i].p; 30 if(sum>m){printf("%d",i-1); goto end;} if(i==n){printf("%d",n); goto end;} 31 } 32 end: return 0; 33 }
20161031