[USACO12FEB]牛券Cow Coupons(堆,贪心)

题目描述

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?

FJ准备买一些新奶牛,市场上有N头奶牛(1<=N<=50000),第i头奶牛价格为Pi(1<=Pi<=109)。FJ有K张优惠券,使用优惠券购买第i头奶牛时价格会降为Ci(1<=Ci<=Pi),每头奶牛只能使用一次优惠券。FJ想知道花不超过M(1<=M<=1014)的钱最多可以买多少奶牛?

输入输出格式

输入格式:

  • 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.

输出格式:

  • Line 1: A single integer, the maximum number of cows FJ can afford.

输入输出样例

输入样例#1:

4 1 7

3 2

2 2

8 1

4 3

输出样例#1:

3

说明

FJ has 4 cows, 1 coupon, and a budget of 7.

FJ uses the coupon on cow 3 and buys cows 1, 2, and 3, for a total cost of 3 + 2 + 1 = 6.

堆模拟反悔操作

很容易发现直接贪心是错误的,因为我们有总钱数的限制。

那么我们可不可以通过调整假的贪心策略来获得正确答案呢?

先贪心地拿最小的k个优惠价,然后考虑怎么反悔。

对于两头牛\(i,j\),假设\(i\)用了优惠券,\(j\)没有用,什么情况下会使\(j\)用优惠券\(i\)不用更优呢?很简单:\(c[i]+p[j]>p[i]+c[j]\)。用一个堆维护用优惠券的牛,令一个堆维护还未选择的牛。每次考虑未选择的牛是用原价买还是“反悔”。

不过自己还有一个疑问,每次钱不够的时候就能够break掉了吗?感觉仔细思考了一下并不可以。希望能够解答

#include<bits/stdc++.h>
#define lll long long
using namespace std;
lll read(){
lll x=0,w=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return x*w;
}
const lll N=50010;
lll n,k,m,ans;
bool vis[N];
struct node{
lll p,c,v;
}f[N];
priority_queue< pair<int,int> >q1,q2;
bool cmp(node p,node q){return p.c<q.c;}
int main(){
n=read();k=read();m=read();
for(lll i=1;i<=n;i++)f[i].p=read(),f[i].c=read(),f[i].v=f[i].p-f[i].c;
sort(f+1,f+1+n,cmp);
for(lll i=1;i<=k;i++){
if(m<f[i].c){cout<<i-1;return 0;}
m-=f[i].c;q1.push(make_pair(f[i].v,i));
}ans=k;
for(lll i=k+1;i<=n;i++)q2.push(make_pair(-f[i].p,i));
while(m&&ans!=n){
lll i=q2.top().second;q2.pop();
lll j=q1.top().second;q1.pop();
if(f[j].c+f[i].p>f[i].c+f[j].p){
if(m<f[j].v+f[i].c)break;
q1.push(make_pair(f[i].v,i));
m-=f[j].v+f[i].c;ans++;
}
else {
if(m<f[i].p)break;
q1.push(make_pair(f[j].v,j));
m-=f[i].p;ans++;
}
}cout<<ans<<endl;
}

[USACO12FEB]牛券Cow Coupons(堆,贪心)的更多相关文章

  1. 洛谷P3045 [USACO12FEB]牛券Cow Coupons

    P3045 [USACO12FEB]牛券Cow Coupons 71通过 248提交 题目提供者洛谷OnlineJudge 标签USACO2012云端 难度提高+/省选- 时空限制1s / 128MB ...

  2. P3045 [USACO12FEB]牛券Cow Coupons

    P3045 [USACO12FEB]牛券Cow Coupons 贪心题.先选中 \(c_i\) 最小的 \(k\) 头牛,如果这样就超过 \(m\) ,直接退出,输出答案.否则考虑把后面的牛依次加入, ...

  3. [USACO12FEB]牛券Cow Coupons

    嘟嘟嘟 这其实是一道贪心题,而不是dp. 首先我们贪心的取有优惠券中价值最小的,并把这些东西都放在优先队列里,然后看[k + 1, n]中,有些东西使用了优惠券减的价钱是否比[1, k]中用了优惠券的 ...

  4. LuoguP3045牛券Cow Coupons

    LuoguP3045 [USACO12FEB]牛券Cow Coupons 果然我贪心能力还是太差了 ZR讲过的原题我回来对做法没有一丁点印象 有时候有这样一种题目 每个数有两种不同的价值 你可以选择价 ...

  5. 牛券Cow Coupons

    USACO12FEB 久违的奶牛题. 题意: FJ准备买一些新奶牛,市场上有 $ N $ 头奶牛 $ (1 \leq N \leq 50000) $ ,第i头奶牛价格为 $ P_i (1 \leq P ...

  6. [Usaco 2012 Feb]Cow coupons牛券:反悔型贪心

    Description Farmer  John  needs  new  cows! There  are  N  cows  for  sale (1 <= N <= 50,000), ...

  7. [USACO 2012 Feb Gold] Cow Coupons【贪心 堆】

    传送门1:http://www.usaco.org/index.php?page=viewproblem2&cpid=118 传送门2:http://www.lydsy.com/JudgeOn ...

  8. [Usaco2012 Feb] Cow Coupons

    [Usaco2012 Feb] Cow Coupons 一个比较正确的贪心写法(跑得贼慢...) 首先我们二分答案,设当前答案为mid 将序列按照用券之后能省掉的多少排序,那么我们对于两种情况 \(m ...

  9. USACO 2012 Feb Cow Coupons

    2590: [Usaco2012 Feb]Cow Coupons Time Limit: 10 Sec Memory Limit: 128 MB Submit: 349 Solved: 181 [Su ...

随机推荐

  1. 四、日志输出Reporter.log

    一.Reporter.log import org.testng.Reporter; public class TestLog { public static void main(String[] a ...

  2. OpenCV学习笔记(3)——图像的基本操作

    获取图像的像素值并修改 获取图像的属性(信息) 图像的ROI() 图像通道的拆分及合并 1.获取并修改像素值 先读入图像装入一个图像实体,然后该实体相当于一个多维list,可以直接用数组操作提取像素信 ...

  3. Redis 配置 CONFIG 命令

    redis.conf 文件在 安装目录下 CONFIG 命令查看或设置配置项 先登陆 src/redis-cli -a -a 后面是密码,默认为空,没有密码直接登陆 src/redis-cli 1.查 ...

  4. puppeteer - 操作支付宝报“操作频繁”错误的思考

    我这里想要实现的是通过转账到支付宝的方式判断一个手机号是否注册过支付宝.但查询收款人的网络请求很复杂分析不出来,使用 puppteer 也是没有解决 "操作频繁" 的问题(应该还有 ...

  5. 匿名内部类 this.val$的问题

    一天偶尔在网上找到一个jar包,反编译后出现了如下的代码: public void defineAnonymousInnerClass(String name)  {    new Thread(na ...

  6. Counter() most_common()

    1 不仅可以统计list中元素的出现次数,也可以对str中的元素进行统计 # collections包中的Counter用于统计str list 中元素出现次数 from collections im ...

  7. Elasticsearch 6.2.3版本 filtered 报错问题 no [query] registered for [filtered]

    背景描述 近期在学习<Elasticsearch 权威指南>上的一些基本命令,在操作到 filtered 进行过滤查询的时候,报错 “no [query] registered for [ ...

  8. 之前写的页面导出Excel表格

    废话不多说,直接上代码 <%@ page language="java" import="java.util.*" pageEncoding=" ...

  9. Centos6.5修改mysql登陆用户密码

    1.修改mysql的登陆设置: vim /etc/my.cnf 并在[mysqld] 下面添加一句:skip-grant-tables=1 添加成功后保存退出. 2.重启mysql并修改密码 重启my ...

  10. ssh端口转发功能

    一.SSH 端口转发能够提供两大功能: 1.加密SSH Client 端至SSH Server 端之间的通讯数据 2.突破防火墙的限制完成一些之前无法建立的TCP 连接  (隧道功能) 二:SSH端口 ...