问题描述

在计算机中,CPU只能和高速缓存Cache直接交换数据。当所需的内存单元不在Cache中时,则需要从主存里把数据调入Cache。此时,如果Cache容量已满,则必须先从中删除一个。 例如,当前Cache容量为3,且已经有编号为10和20的主存单元。 此时,CPU访问编号为10的主存单元,Cache命中。 接着,CPU访问编号为21的主存单元,那么只需将该主存单元移入Cache中,造成一次缺失(Cache Miss)。 接着,CPU访问编号为31的主存单元,则必须从Cache中换出一块,才能将编号为31的主存单元移入Cache,假设我们移出了编号为10的主存单元。 接着,CPU再次访问编号为10的主存单元,则又引起了一次缺失。我们看到,如果在上一次删除时,删除其他的单元,则可以避免本次访问的缺失。 在现代计算机中,往往采用LRU(最近最少使用)的算法来进行Cache调度——可是,从上一个例子就能看出,这并不是最优的算法。 对于一个固定容量的空Cache和连续的若干主存访问请求,聪聪想知道如何在每次Cache缺失时换出正确的主存单元,以达到最少的Cache缺失次数。

输入格式

输入文件第一行包含两个整数N和M(1<=M<=N<=100,000),分别代表了主存访问的次数和Cache的容量。 第二行包含了N个空格分开的正整数,按访问请求先后顺序给出了每个主存块的编号(不超过1,000,000,000)。

输出格式

输出一行,为Cache缺失次数的最小值。

样例输入

6 2

1 2 3 1 2 3

样例输出

4

样例解释

在第4次缺失时将3号单元换出Cache。

解析

感性理解一下,每次换出下一次出现最远的是最优的。那么我们用优先队列维护Cache中的主存单元,排序关键字为下一次出现的位置,如果目前插入的元素已经在队列中了,就直接插入队列,否则若Cache已满就弹出队首元素再插入,若没满就直接插入。具体还可以用set辅助实现。

代码

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <set>
#include <queue>
#define N 100002
using namespace std;
struct task{
int id,p,nxt;
bool operator < (const task &x) const{
return x.nxt>nxt;
}
}a[N];
int n,m,i,c,ans;
priority_queue<task> q;
set<int> s;
int cmp1(const task &x,const task &y)
{
if(x.id==y.id) return x.p<y.p;
return x.id<y.id;
}
int cmp2(const task &x,const task &y)
{
return x.p<y.p;
}
int main()
{
cin>>n>>m;
for(i=1;i<=n;i++){
cin>>a[i].id;
a[i].p=i;
}
sort(a+1,a+n+1,cmp1);
for(i=2;i<=n+1;i++){
if(a[i].id==a[i-1].id) a[i-1].nxt=a[i].p;
else a[i-1].nxt=1<<30;
}
sort(a+1,a+n+1,cmp2);
for(i=1;i<=n;i++){
int x=a[i].id;
if(s.count(x)){
q.push(a[i]);
continue;
}
ans++;
if(s.size()==m) s.erase(q.top().id),q.pop();
s.insert(x);
q.push(a[i]);
}
cout<<ans<<endl;
return 0;
}

[BZOJ1826] 缓存交换的更多相关文章

  1. 【BZOJ1826】[JSOI2010]缓存交换(贪心)

    [BZOJ1826][JSOI2010]缓存交换(贪心) 题面 BZOJ 洛谷 题解 当缓存不满显然直接放进去,满了之后考虑拿走哪一个.不难发现拿走下一次出现时间最晚的那个一定不会更差. 那么用一个堆 ...

  2. bzoj1528[POI2005]sam-Toy Cars*&&bzoj1826[JSOI2010]缓存交换

    bzoj1528[POI2005]sam-Toy Cars bzoj1826[JSOI2010]缓存交换 题意: Jasio有n个不同的玩具,它们都被放在了很高的架子上,地板上不会有超过k个玩具.当J ...

  3. BZOJ_1826_[JSOI2010]缓存交换 _线段树+贪心

    BZOJ_1826_[JSOI2010]缓存交换 _线段树+贪心 Description 在计算机中,CPU只能和高速缓存Cache直接交换数据.当所需的内存单元不在Cache中时,则需要从主存里把数 ...

  4. 1826: [JSOI2010]缓存交换

    1826: [JSOI2010]缓存交换 https://www.lydsy.com/JudgeOnline/problem.php?id=1826 分析: 简单的贪心,然后调啊调...最近怎么了,码 ...

  5. 无缓存交换 牛客网 程序员面试金典 C++ Python

    无缓存交换 牛客网 程序员面试金典 C++ Python 题目描述 请编写一个函数,函数内不使用任何临时变量,直接交换两个数的值. 给定一个int数组AB,其第零个元素和第一个元素为待交换的值,请返回 ...

  6. BZOJ1826 [JSOI2010]缓存交换 堆 贪心

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1826 题意概括 Cache中有m个储存单元,接下来有n个访问地址,每个地址用一个数字表示.访问每一 ...

  7. [bzoj1826] [JSOI2010]缓存交换

    虽然不知道为什么..但显然,每次扔掉离下次查询最远的内存单元就行了233 用堆来维护贪心...(优先队列大法好 #include<cstdio> #include<iostream& ...

  8. Luogu P4404 [JSOI2010]缓存交换 优先队列

    细节题?...调了半天.... 可以发现,每一次从缓存中删除的主存一定是下次访问最晚的,可以用优先队列来处理...还有要离散化...还有链表末尾要多建一些点...否则会死的很惨... #include ...

  9. B1826 [JSOI2010]缓存交换 贪心+离散化+堆

    这个题仔细一想可以直接贪心做,因为队列里下一个出现的早的一定最优.正确性显然.然后我只拿了50,我直接模拟另一个队列暴力修改最后一个点的nxt值,自然会T.但是其实不用修改,直接插入就行了前面的不影响 ...

随机推荐

  1. CentOS7 日常操作 2

    常用命令 文件与目录操作 命令 解析 cd /home 进入 ‘/home’ 目录 cd .. 返回上一级目录 cd ../.. 返回上两级目录 cd - 返回上次所在目录 cp file1 file ...

  2. R 时间戳转化

    转 http://stackoverflow.com/questions/1962278/dealing-with-timestamps-in-r You want the (standard) PO ...

  3. sqlserver通过select查询出连续的日历临时表

    首先我们需要用到这个 select * FROM master..spt_values n WHERE n.type = 'p' AND n.number <= 7 里面分几个列,我们需要连续的 ...

  4. axios 拦截以及 API简单配置(element)

    在某些情况下,有时候会在接口请求的API中需要拿到存在浏览器中的COOKIE,调用的方式可以为: // 获取浏览器Cookie function getCookie(cname) { var name ...

  5. AlertManager警报通知 E-mail 微信 模板

    # AlertManager警报通知 E-mail 微信 模板 #AlertManager配置 #alertmanager.yml # 全局配置项 global: resolve_timeout: 5 ...

  6. 003/kubernetes基础:开启云原生之门(Mooc)

    一.简介:(https://www.imooc.com/learn/978) 在2017年Kubernetes战胜了两个强大的竞争对手Swarm和Mesos,成为容器管理与调度编排领域的首选平台和事实 ...

  7. 压缩图片工具类,压缩100KB以内拿走直接用

    最近遇到自拍上传图片过大问题,很烦恼,所以自己写了一个压缩图片的工具类使用,自测效果很不错,可以压缩到KB以内,像素还可以分辨清晰 下面Java代码奉上: import lombok.extern.s ...

  8. Linux 系统下的7个运行级别

    转自:http://blog.chinaunix.net/uid-22746363-id-383989.html Linux系统有7个运行级别(runlevel)运行级别0:系统停机状态,系统默认运行 ...

  9. Maven-maven安装、Eclipse配置maven

    1.下载maven安装包,下载完成,解压到安装路径. 2.配置环境变量 3.修改setting.xml配置本地库,阿里云中央仓库 路径:C:\fyliu\software\apache-maven-3 ...

  10. c++ const 修饰变量位置含义

    c++ const 修饰变量位置含义 const 修饰成员变量 const修饰指针变量时: 只有一个const,如果const位于*左侧,表示指针所指数据是常量,也就是指向常量的指针,不能通过解引用修 ...