愿各位程序员都能记住,输出第一条hello world时候的心情。坚持下去,你的每一条代码都在默默的改变世界,加油!加油!加油! “这些年我一直提醒自己一件事情,千万不要自己感动自己。大部分人看似的努力,不过是愚蠢导致的。 什么熬夜看书到天亮,连续几天只睡几小时,多久没放假了,如果这些东西也值得夸耀,那么富士康流水线上任何一个人都比你努力多了。 人难免天生有自怜的情绪,唯有时刻保持清醒,才能看清真正的价值在哪里。

[Usaco2012 Feb]Cow Coupons 买牛 或 牛券

 

本人水平有限,题解不到为处,请多多谅解

 

本蒟蒻谢谢大家观看

 

题目:传送门

 

 

本题时带有反悔操作的贪心

我们可以先按优惠价给他们排序,可以保证序列值从小到大最优(优惠价比原价小)

取前k头奶牛(k张优惠券),但不一定会在它们身上用上优惠券之后我们可以用反悔操作但此时一定为最优,再用总钱数不断减去,若当总钱数<0时,我们不用继续往下找了,前k个数一定最小的,所以统计完之后直接return 掉

若取完前k头牛钱还有剩余的话,我们又分为两种情况

1:若k之后的当前点不用券,那就要维护一个原价sort,不断贪心

2:若k之后的当前点要有券,那么用差值维护一个小根堆,不断贪心

 

 

注意记得开long long

数据范围很大

 

code:

 1 #include<bits/stdc++.h>
 2 #pragma GCC optimize(3)
 3 #define int long long
 4 using namespace std; 
 5 const int INF=5e18;
 6 priority_queue<int,vector<int>,greater<int> >q;
 7 int ans=0,n,k,m,hhh;
 8 inline int read(){
 9     int x=0,f=1;char ch=getchar();
10     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
11     while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
12     return x*f;
13 }
14 struct oo{
15     int p,c;
16     bool use;
17 }cow[51000];
18 bool cmp1(oo aa,oo bb){
19     return aa.c<bb.c;
20 }
21 bool cmp2(oo aa,oo bb){
22     return aa.p<bb.p;
23 }
24 signed main()
25 {    
26     n=read(),k=read(),m=read();
27     for(int i=1;i<=n;i++){
28         cow[i].p=read(),cow[i].c=read();
29     }
30     sort(cow+1,cow+1+n,cmp1);//按优惠价排列贪心 
31     for(int i=1;i<=k;i++){
32         m-=cow[i].c;
33         if(m>=0){
34             ans++;
35         }
36         else{
37             printf("%lld\n",ans);
38             return 0;
39         }
40         q.push(cow[i].p-cow[i].c);//预处理反悔,方便赎回券 
41     }
42     sort(cow+1+k,cow+1+n,cmp2);//取完前k头牛之后的,按原价排列(无券可用) 
43     for(int i=k+1;i<=n;i++){
44         if(q.empty()){
45             hhh=INF;//如果堆为空,因为此题要求取min,所以初始最大化 
46         }
47         else{
48             hhh=q.top();//如果堆不为空,取出堆顶 
49         }
50         if(hhh+cow[i].c<cow[i].p){
51         //如果赎回一张券来用给j的话,判断反悔时赎金+使用券后的钱与不用券的值比 
52             m-=q.top()+cow[i].c;//如果小于,用券给j,记下小值 
53             q.pop();//出堆 
54             q.push(cow[i].p-cow[i].c);//继续贪心 
55             //因为取走了cow[i].p-cow[i].c 所以继续push进堆 
56         }
57         else{
58             m-=cow[i].p;//否则不用券给j,直接累加取最优 
59         }
60         if(m>=0){
61             ans++;//判断此时手上的钱是否大于0,大于0就表示可以买这头牛 
62         }
63         else{
64             printf("%lld\n",ans);//否则钱不够,后面肯定也买不起,直接break 
65             return 0;
66         }
67     }
68     printf("%lld\n",ans);//输出答案即可 
69     return 0;
70 }

 

posted @ 2019-10-18 11:34  max_lemon  阅读(219)  评论(0编辑  收藏  举报
Live2D
别人恋爱不成功,你连暗恋都不成功! 你写不出代码的原因只有一个,那就是你没有彻底理解这个算法的思想!!-----沃茨·基硕德