https://www.luogu.org/problem/P4404

题意

你有一个大小为n的缓存区,有个长度为m的查询序列。

每次查询的时候需要把查询值放入缓存,若缓存已满,则先删除任一位置再将其放入,若缓存内已有当前值,则无需再次放入

求放入缓存这个操作的最少执行次数

n,m≤1e5

序列中的数<=1,000,000,000

分析

很明显的贪心, 但要想想贪心的策略

其实这题做的很玄(感觉我每次做题都很玄,因为是听完luogu讲师讲完之后做的题目,思路什么的都有提示...

这道题首先要做的就是把前m个不同的数放到缓存里面,然后依次加数,删数...也就是一个模拟。

但怎么删数呢?这里给出的策略是删除缓存中一个数x: 在缓存外,x对应的第一个与它相等的数y 的位置最靠后。

原因:(我只知道这样做是对的,但不知道怎么想到的...毕竟我只画了几个例子,思路老师说的)

这样子做,可以使删除操作对放入缓存次数的影响最小,即 使放入缓存的操作数增加的最小,如果我们不这做,那么 y 之前必定有数z,经历了先删除又放入,而先删x的话,至少不会使放入缓存的操作更多....吧(我其实也不是hin懂,看看实现就行了

实现:预处理一下y(即代码中的next),用堆存这个玩意,注意离散化,注意模拟的过程就好了

实现

#include<cstdio>
#include<algorithm>
#include<string.h>
#include<queue>
using namespace std;
#define MAX 100000+9 int n,m,ans, tag = 1;
struct node{
int a,n,k;
}a[MAX];
bool cmp1(node x, node xxx) { return x.a < xxx.a;}
bool cmp2(node x, node xxx) { return x.n < xxx.n;} int last[MAX], next[MAX], vis[MAX];
struct node2{
int num, next;
bool operator < (const node2& xxx) const {
return next < xxx.next ;
}
}; priority_queue<node2> q; int main() {
scanf("%d%d",&n,&m);
for(int i = 1; i <= n; i++) scanf("%d",&a[i].a ), a[i].n = i;
sort(a+1, a+1+n, cmp1);
int tot = 0;
for(int i = 1; i <= n; i++) {
a[i].k = ++tot;
while(a[i+1].a == a[i].a ) a[++i].k = tot;
}
sort(a+1, a+1+n, cmp2);
// for(int i = 1; i <= n; i++) printf("%d ",a[i].k );
// printf("\n");
//注意,若满的缓存区里有一元素x,并且查询序列中没有了x,那么x一定是要先删的,所以设为INF
memset(last , 0x3f , sizeof(last));
for(int i = n; i >= 1; i--) {
next[i] = last[a[i].k ];
last[a[i].k ] = i;
}
// for(int i = 1; i <= n; i++) printf("%d ",next[i] );
// printf("\n");
for(int i = 1; i <= n; i++) {
if(ans == m) {
tag = 2;
}
if(tag == 1 && vis[a[i].k] == 0) {//没放满m ,且a[i].k不在队中
ans++;
vis[a[i].k ] = 1;
}
if(tag == 2 && vis[a[i].k] == 0) {//放满的m,且a[i].k不在队中
ans++;
vis[a[i].k ] = 1;
vis[q.top().num] = 0;
q.pop();
}
node2 tmp;
tmp.num = a[i].k , tmp.next = next[i];
q.push(tmp);
}
printf("%d",ans);
return 0;
}
/*
6 2
1 222 3333 1 222 3333
*/

luoguP4404缓存交换的更多相关文章

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

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

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

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

  3. 1826: [JSOI2010]缓存交换

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

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

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

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

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

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

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

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

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

  8. [BZOJ1826] 缓存交换

    问题描述 在计算机中,CPU只能和高速缓存Cache直接交换数据.当所需的内存单元不在Cache中时,则需要从主存里把数据调入Cache.此时,如果Cache容量已满,则必须先从中删除一个. 例如,当 ...

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

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

随机推荐

  1. Django模版中加载静态文件配置详解

    .settings.INSTALLED_APPS下添加:django.contrib.staticfiles .settings.py下添加:STATIC_URL = '/static/' . ()在 ...

  2. 多个div使用display:inline-block时候div之间有间隔

    开发场景中用到display:inline-block;然后呢,div间就有间隙,但是ajax加载出来的数据没有间隙,解决办法如下   display:inline-block表示行内块元素,后面自带 ...

  3. Day3 - Python基础3 函数基本、递归函数、内置函数

    本节内容 1. 函数基本语法及特性 2. 参数与局部变量 2.2. 函数变量作用域 3. 返回值 嵌套函数 4.递归 5.匿名函数 6.函数式编程介绍 7.高阶函数 8.内置函数 1. 函数基本语法及 ...

  4. 一个页面从输入url到加载到内容,这个过程经历了什么

    首先,当浏览器接收到url,会查看本地缓存(浏览器缓存-系统缓存-路由器缓存)中是否有,有则直接显示 没有则进行DNS域名解析,将域名解析成IP地址,通过ip地址去访问相应的服务器, 浏览器访问服务器 ...

  5. QT新建空白项目-添加QT设计师界面类时出现的各种库无法导入识别

    按照教材上先新建一个空的项目--添加Qt设计师界面类时 出现各种 库无法识别 解决方法: 在 .pro文件中加入一行 QT += widgets 去构建中先执行 qmake 然后再构建一下  ok了 ...

  6. 微信公众号开发 ,redirect_uri域名还是与后台配置不一致

    测试账号地址: https://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index https ...

  7. Linux下修改Mysql密码的三种方式

    前言 有时我们会忘记Mysql的密码,或者想改一个密码,以下将对这两种情况修改密码的三种解决方法做个总结 本文都以用户为 root 为例 一.拥有原来的myql的root的密码 方法一: 在mysql ...

  8. 《转》crontab 定时任务

    命令格式 crontab [-u user] file crontab [-u user] [-e | -l | -r | -i ] 命令参数 -u user:用来设定某个用户的crontab服务,例 ...

  9. Jmeter之用于json格式的响应断言

    当响应结果是json格式时,用JSON Assertion更方便判断. 1 在请求上右键添加json断言 2  编辑json Assertion 判断方式: 如果响应结果不是json格式的,fail ...

  10. WPF 启动页面 (原发布 csdn 2017-06-26 19:26:01)

    如果我写的有误,请及时与我联系,我立即改之以免继续误导他/她人. 如果您有好的想法或者建议,请随时与我联系. wpf软件启动时,加载启动页面.软件初始化完成之后关闭页面. App.xaml.cs代码 ...