首页 > 代码库 > bzoj2590[Usaco2012 Feb]Cow Coupons*

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

bzoj2590[Usaco2012 Feb]Cow Coupons*