luoguP4404缓存交换
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缓存交换的更多相关文章
- BZOJ_1826_[JSOI2010]缓存交换 _线段树+贪心
BZOJ_1826_[JSOI2010]缓存交换 _线段树+贪心 Description 在计算机中,CPU只能和高速缓存Cache直接交换数据.当所需的内存单元不在Cache中时,则需要从主存里把数 ...
- 【BZOJ1826】[JSOI2010]缓存交换(贪心)
[BZOJ1826][JSOI2010]缓存交换(贪心) 题面 BZOJ 洛谷 题解 当缓存不满显然直接放进去,满了之后考虑拿走哪一个.不难发现拿走下一次出现时间最晚的那个一定不会更差. 那么用一个堆 ...
- 1826: [JSOI2010]缓存交换
1826: [JSOI2010]缓存交换 https://www.lydsy.com/JudgeOnline/problem.php?id=1826 分析: 简单的贪心,然后调啊调...最近怎么了,码 ...
- bzoj1528[POI2005]sam-Toy Cars*&&bzoj1826[JSOI2010]缓存交换
bzoj1528[POI2005]sam-Toy Cars bzoj1826[JSOI2010]缓存交换 题意: Jasio有n个不同的玩具,它们都被放在了很高的架子上,地板上不会有超过k个玩具.当J ...
- 无缓存交换 牛客网 程序员面试金典 C++ Python
无缓存交换 牛客网 程序员面试金典 C++ Python 题目描述 请编写一个函数,函数内不使用任何临时变量,直接交换两个数的值. 给定一个int数组AB,其第零个元素和第一个元素为待交换的值,请返回 ...
- Luogu P4404 [JSOI2010]缓存交换 优先队列
细节题?...调了半天.... 可以发现,每一次从缓存中删除的主存一定是下次访问最晚的,可以用优先队列来处理...还有要离散化...还有链表末尾要多建一些点...否则会死的很惨... #include ...
- B1826 [JSOI2010]缓存交换 贪心+离散化+堆
这个题仔细一想可以直接贪心做,因为队列里下一个出现的早的一定最优.正确性显然.然后我只拿了50,我直接模拟另一个队列暴力修改最后一个点的nxt值,自然会T.但是其实不用修改,直接插入就行了前面的不影响 ...
- [BZOJ1826] 缓存交换
问题描述 在计算机中,CPU只能和高速缓存Cache直接交换数据.当所需的内存单元不在Cache中时,则需要从主存里把数据调入Cache.此时,如果Cache容量已满,则必须先从中删除一个. 例如,当 ...
- [bzoj1826] [JSOI2010]缓存交换
虽然不知道为什么..但显然,每次扔掉离下次查询最远的内存单元就行了233 用堆来维护贪心...(优先队列大法好 #include<cstdio> #include<iostream& ...
随机推荐
- maven配置本地和远程仓库
maven项目中我们不用挨个导入jar包,那这些Jar包从哪里来呢?当你建立一个 Maven 的项目,Maven 会检查你的 pom.xml 文件,以确定哪些依赖下载.首先,Maven 将从本地资源库 ...
- Codeforces Round #578 (Div. 2)
Codeforces Round #578 (Div. 2) 传送门 A. Hotelier 暴力即可. Code #include <bits/stdc++.h> using names ...
- 异常类的构建——顶层父类Exception的实现
异常类构建异常的类型可以是自定义类类型对于类类型异常的匹配依旧是从上到下严格的匹配赋值兼容性原则在异常匹配中依然适用一般而言-匹配子类异常的catch放在上部-匹配父类异常的catch放在下部 现代C ...
- 题解:swj社会摇成佛第六课
题目链接 solution: dp f[i]表示lhy小伙身长为i,能砍得的最优解 f[i]=f[j]*f[i-j]; public class CuttingRope01 { public stat ...
- 超实用的Java web面试题
Java web面试题 1.Tomcat的优化经验 答:去掉对web.xml的监视,把jsp提前编辑成Servlet. 有富余物理内存的情况,加大tomcat使用的jvm的内存 2.HTTP请求的GE ...
- POI2008 CLO-Toll
[POI2008]CLO-Toll 题意描述 Byteotia城市有n个 towns m条双向roads. 每条 road 连接 两个不同的 towns ,没有重复的road. 你要把其中一些road ...
- 洛谷 P5640 【CSGRound2】逐梦者的初心
洛谷 P5640 [CSGRound2]逐梦者的初心 洛谷传送门 题目背景 注意:本题时限修改至250ms,并且数据进行大幅度加强.本题强制开启O2优化,并且不再重测,请大家自己重新提交. 由于Y校的 ...
- String的源码理解(未写完)
String本质上是一个char数组(jdk 9之后是byte数组),并且是一个声明为final的数组,并且String的不可变也是通过这种把数组声明为final来实现的 public final c ...
- WPF 绑定属性 XAML 时间格式化
原文:WPF 绑定属性 XAML 时间格式化 XAML 时间格式化{Binding Birthday,StringFormat='yyyy-MM-dd '} public class AssetCla ...
- Python骚操作:Python控制Excel实现自动化办公!
1.安装 2.操作一个简单的Excel文档 操作注释及代码: 操作完成后,数据存储结果如下: 3. 操作简单Excel文档并添加数据格式 操作代码如下:附带数据格式的定义 操作效果 ...