http://codeforces.com/contest/802/problem/B

【题意】

有一个图书馆,刚开始没有书,最多可容纳k本书;有n天,每天会有人借一本书,当天归还;如果图书馆有这个本就直接借到,否则图书馆的人会购买这本书,每本书的价格都是1;如果现在图书馆的书已达上限还需购买,必须舍弃已有的一本书,以后再有人借这本书要重新购买。

问图书馆的人最少要花多少钱购书?

数据范围变成了4000 00.

【思路】

关键是替换原则,每次都替换下一次出现最晚的,因为它占用图书馆的时间最长。

【官方题解】

Here we need to be much more ecient. There are many data structures that one can use. One idea is to
store a queue of remaining requests for each possible book (initializing it at the beginning and removing
requests from the front as they arrive) and an std::set-like structure (based on a balanced binary search
tree; it is also possible to use a priority queue based on a heap) which stores books that are currently at the
library, sorted by their next-request time.

这里我用优先级队列找出每次应该替换哪一个,用队列记录每个图书馆中的元素出现位置的情况,不断更新pq和q。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<vector>
#include<algorithm>
#include<queue>
#include<map>
using namespace std;
typedef long long ll;
const int maxn=4e5+;
int a[maxn];
int b[maxn];
map<int,int> mp;
struct Node
{
int id;
int num;
Node(int iid,int nnum):id(iid),num(nnum){}
};
//根据id排序,优先级队列先pop的是排在后面的,也就是下一次出现最晚的
bool operator<(Node a,Node b)
{
return a.id<b.id;
}
//每个数都有一个出现位置的队列
queue<int> q[maxn];
priority_queue<Node> pq;
int vis[maxn];
int n,m;
int main()
{
while(~scanf("%d%d",&n,&m))
{
memset(vis,,sizeof(vis));
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
}
int ans=;
int cnt=;
int i;
for(i=;i<=n;i++)
{
if(cnt<m)
{
if(!vis[a[i]])
{
b[++cnt]=a[i];
vis[a[i]]=;
ans++;
}
}
else
{
break;
}
}
if(cnt<m)
{
printf("%d\n",ans);
continue;
}
//q[a[k]] 为a[k]从小到大出现位置的队列 ,要从i开始算,以前的都不用记
for(int k=i;k<=n;k++)
{
q[a[k]].push(k);
}
for(int k=;k<=cnt;k++)
{
if(!q[b[k]].empty())
{
pq.push(Node(q[b[k]].front(),b[k]));
}
else
{
//maxn代表后面不出现
pq.push(Node(maxn,b[k]));
}
//b[1,cnt]中记录的始终是当前图书馆的书,每个元素都不同,是一个一一映射
mp[b[k]]=k;
}
for(;i<=n;i++)
{
if(!q[a[i]].empty())
{
q[a[i]].pop();
}
if(!vis[a[i]])
{
ans++;
Node node=pq.top();
pq.pop();
//根据node.num映射到对应b中的位置
int id=mp[node.num];
vis[b[id]]=;
b[id]=a[i];
vis[a[i]]=;
//更新后的映射
mp[a[i]]=id;
}
//要放在后面,否则会影响前面的pop
if(!q[a[i]].empty())
{
pq.push(Node(q[a[i]].front(),a[i]));
}
else
{
pq.push(Node(maxn,a[i]));
}
}
printf("%d\n",ans);
}
return ;
}

【贪心】codeforces B. Heidi and Library (medium)的更多相关文章

  1. 【贪心】codeforces A. Heidi and Library (easy)

    http://codeforces.com/contest/802/problem/A [题意] 有一个图书馆,刚开始没有书,最多可容纳k本书:有n天,每天会有人借一本书,当天归还:如果图书馆有这个本 ...

  2. 【网络流】codeforces C. Heidi and Library (hard)

    http://codeforces.com/contest/802/problem/C

  3. 贪心算法 Heidi and Library (easy)

    A. Heidi and Library (easy) time limit per test 2 seconds memory limit per test 256 megabytes input ...

  4. 题解-CF802C Heidi and Library (hard)

    题面 CF802C Heidi and Library (hard) 有一个大小为 \(k\) 的空书架.有 \(n\) 天和 \(n\) 种书,每天要求书架中有书 \(a_i\).每天可以多次买书, ...

  5. 【CF802C】Heidi and Library(网络流)

    [CF802C]Heidi and Library(网络流) 题面 CF 洛谷 题解 前面两个Easy和Medium都是什么鬼玩意啊.... 不难发现如果这天的要求就是第\(a_i\)种书的话,那么\ ...

  6. C. Heidi and Library (神奇的网络流)

    C. Heidi and Library 题意 有 n 种分别具有价格 b 的书 a ,图书馆里最多同时存放 k 本书,已知接下来 n 天每天都有一个人来看某一本书,如果图书馆里没有则需要购买,问最少 ...

  7. CF802C Heidi and Library hard 费用流 区间k覆盖问题

    LINK:Heidi and Library 先说一下简单版本的 就是权值都为1. 一直无脑加书 然后发现会引起冲突,可以发现此时需要扔掉一本书. 扔掉的话 可以考虑扔掉哪一本是最优的 可以发现扔掉n ...

  8. 【CF802C】Heidi and Library (hard) 费用流

    [CF802C]Heidi and Library (hard) 题意:有n个人依次来借书,第i人来的时候要求书店里必须有种类为ai的书,种类为i的书要花费ci块钱购入.而书店的容量只有k,多余的书只 ...

  9. Codeforces 802 ABC. Heidi and Library

    题目大意 你需要保证第\(i\)天时有第\(a_i\)种书.你可以在任何一天买书,买第\(i\)种书的代价为\(c_i\). 你最多同时拥有\(k\)本书,如果此时再买书,则必须先扔掉已拥有的一本书. ...

随机推荐

  1. angularjs 下select中ng-options使用

    当我有一堆object数据要用下拉框进行显示选择时,可以使用到angularjs中的select中的ng-options的属性.官网网址:https://docs.angularjs.org/api/ ...

  2. 进度条--ProgressBar和BackgroundWorker

    1) 需求:就餐打卡数据处理后,插入数据库中,用进度条显示过程 2) 思路:总进度为txt文本文件的行数(数据都是按照行写入),文本文件的大小 //BackgroundWorker对象有三个主要的事件 ...

  3. ios微信浏览器click事件不起作用的解决方法

    $(document).on( "click", ".weui_cell", function (event) {alert(); }); JS代码是这样的,h ...

  4. iOS 蒲公英第三方打包平台

    http://www.pgyer.com/doc/view/ios_install_failed

  5. 使用代码编辑器Sublime Text 3进行前端开发及相关快捷键

    推荐理由: Sublime Text:一款具有代码高亮.语法提示.自动完成且反应快速的编辑器软件,不仅具有华丽的界面,还支持插件扩展机制,用她来写代码,绝对是一种享受.相比于浮肿沉重的Eclipse, ...

  6. win7创建无线(WIFI)cmd命令

    1.创建无限热点:netsh wlan set hostednetwork mode=allow ssid=name key=12345678. 2.承载网络:netsh wlan start(关闭s ...

  7. 洛谷 P2515 [HAOI2010]软件安装

    题目描述 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁盘容量为M计算机上,使得这些软件的价值尽可能大(即Vi的和最大). 但是 ...

  8. js toString() 方法 Number() 方法 等 类型转换

    1.1 数字类型转字符串 String() 变量.toString() toString() 方法 toString() 方法可把一个逻辑值转换为字符串,并返回结果. 1.2 字符串转数字类型 Num ...

  9. 检查bug

    用selective_search生成的坐标是(ymin,xmin,ymax,xmax),并且是从1开始的,不是从0 这是cache中的gt数据,明显看到有65535,说明很有可能是0-1变成了655 ...

  10. Java垃圾回收之新生代垃圾收集器

    问题:什么是Stop-the-World? 1.JVM由于要执行GC而停止了应用程序的执行 2.任何一种GC算法中都会发生 3.多数GC优化通过减少Stop-the-world发生的时间来提高程序的性 ...