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。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<string>
  5. #include<cmath>
  6. #include<vector>
  7. #include<algorithm>
  8. #include<queue>
  9. #include<map>
  10. using namespace std;
  11. typedef long long ll;
  12. const int maxn=4e5+;
  13. int a[maxn];
  14. int b[maxn];
  15. map<int,int> mp;
  16. struct Node
  17. {
  18. int id;
  19. int num;
  20. Node(int iid,int nnum):id(iid),num(nnum){}
  21. };
  22. //根据id排序,优先级队列先pop的是排在后面的,也就是下一次出现最晚的
  23. bool operator<(Node a,Node b)
  24. {
  25. return a.id<b.id;
  26. }
  27. //每个数都有一个出现位置的队列
  28. queue<int> q[maxn];
  29. priority_queue<Node> pq;
  30. int vis[maxn];
  31. int n,m;
  32. int main()
  33. {
  34. while(~scanf("%d%d",&n,&m))
  35. {
  36. memset(vis,,sizeof(vis));
  37. for(int i=;i<=n;i++)
  38. {
  39. scanf("%d",&a[i]);
  40. }
  41. int ans=;
  42. int cnt=;
  43. int i;
  44. for(i=;i<=n;i++)
  45. {
  46. if(cnt<m)
  47. {
  48. if(!vis[a[i]])
  49. {
  50. b[++cnt]=a[i];
  51. vis[a[i]]=;
  52. ans++;
  53. }
  54. }
  55. else
  56. {
  57. break;
  58. }
  59. }
  60. if(cnt<m)
  61. {
  62. printf("%d\n",ans);
  63. continue;
  64. }
  65. //q[a[k]] 为a[k]从小到大出现位置的队列 ,要从i开始算,以前的都不用记
  66. for(int k=i;k<=n;k++)
  67. {
  68. q[a[k]].push(k);
  69. }
  70. for(int k=;k<=cnt;k++)
  71. {
  72. if(!q[b[k]].empty())
  73. {
  74. pq.push(Node(q[b[k]].front(),b[k]));
  75. }
  76. else
  77. {
  78. //maxn代表后面不出现
  79. pq.push(Node(maxn,b[k]));
  80. }
  81. //b[1,cnt]中记录的始终是当前图书馆的书,每个元素都不同,是一个一一映射
  82. mp[b[k]]=k;
  83. }
  84. for(;i<=n;i++)
  85. {
  86. if(!q[a[i]].empty())
  87. {
  88. q[a[i]].pop();
  89. }
  90. if(!vis[a[i]])
  91. {
  92. ans++;
  93. Node node=pq.top();
  94. pq.pop();
  95. //根据node.num映射到对应b中的位置
  96. int id=mp[node.num];
  97. vis[b[id]]=;
  98. b[id]=a[i];
  99. vis[a[i]]=;
  100. //更新后的映射
  101. mp[a[i]]=id;
  102. }
  103. //要放在后面,否则会影响前面的pop
  104. if(!q[a[i]].empty())
  105. {
  106. pq.push(Node(q[a[i]].front(),a[i]));
  107. }
  108. else
  109. {
  110. pq.push(Node(maxn,a[i]));
  111. }
  112. }
  113. printf("%d\n",ans);
  114. }
  115. return ;
  116. }

【贪心】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. 多线程wait和notify实现1212

    package threadT; public class ThreadMain { public static void main(String args[]) { final Object obj ...

  2. Docker DOC

    Docker DOC docker是提供给开发或管理人员的容器化部署项目工具 在linux上运行docker 常用命令 docker 安装 #先更新yum yum update; #设置docker仓 ...

  3. f# mathprovider

    http://mathprovider.codeplex.com/ http://mathnetnumerics.codeplex.com/releases/view/110750 http://py ...

  4. P1303 A*B Problem

    题目描述 求两数的积. 输入输出格式 输入格式: 两个数 输出格式: 积 输入输出样例 输入样例#1: 1 2 输出样例#1: 2 说明 需用高精 #include<iostream> # ...

  5. iOS 应用程序内部国际化,不跟随系统语言

    前言:网络上关于iOS国际化的文章很多,但基本上都是基于跟随系统语言的国际化,笔者就不赘述了-0 – 今天要讲的是不跟随系统的切换语言版本方案,即程序内部的切换语言版本方案. 一.总则: 应用内部语言 ...

  6. 【Android】ListView中EditText焦点问题

    一.描述: 近期一个项目中需要开发一种类似表格的界面来显示和配置参数,Android并无直接类似表格的控件支持,我采用了ListView中布局EditText和TextView来实现,其中TextVi ...

  7. 嵌入式C语言-学习书籍推荐(pdf附上百度云链接)

    先推荐学习视频网站: https://www.bilibili.com/video/av22631677?from=search&seid=800092160484173881 书籍只推荐2本 ...

  8. 联玛客(W 笔试)

    纸质算法题 1. 输入数据:1.3.2.4.8... 输出数据:3.1.4.2.8... 找出规律,写出一个程序求解,并附上时间复杂度和空间复杂度 我的答案: 规律一:奇偶位互换 假设输入数据长度为5 ...

  9. 目标检测中bounding box regression

    https://zhuanlan.zhihu.com/p/26938549 RCNN实际包含两个子步骤,一是对上一步的输出向量进行分类(需要根据特征训练分类器):二是通过边界回归(bounding-b ...

  10. java程序中中文没有乱码,存入数据库后中文乱码问题

    jdbc.driver=com.mysql.jdbc.Driverjdbc.url=jdbc:mysql://localhost:3306/sys_user?useOldAliasMetadataBe ...