NC15688 Operating System
题目
题目描述
在学习Operating System的过程中,Glory遇到了这样一个问题,现在有一个大小为可以容纳N个页面的内存,硬盘内的内容被分成M个页面,用1~M来标识,一开始内存里没有任何页面,接下来用户会请求Q个页面,你需要设计一个置换算法,使得缺页发生的次数最少。缺页是指用户请求某个编号的页面,但这个页面没有在内存中的情况。发生缺页之后,你必须要把硬盘内对应的页面调入内存中,如果内存已满,你需要置换掉当前内存中的某个页面。
输入描述
多组数据,请处理到输入结束。
每组数据,第一行为三个整数N,M,Q (0 < N,M,Q <= 50000)
接下来一行Q个数,表示用户请求的页面编号。
输出描述
对于每组数据,输出一个数,表示最少的缺页次数。
示例1
输入
2 3 5 3 1 2 1 2 3 4 5 3 2 1 4 3
输出
3 4
题解
知识点:贪心,优先队列。
显然,OPT算法贪心一下即可,预处理后用优先队列维护。具体可以看我另一篇博客 **“NC20185 [JSOI2010]缓存交换” ** 。
时间复杂度
空间复杂度
代码
#include <bits/stdc++.h> using namespace std; int a[50007], last[50007], nxt[50007], vis[50007]; int main() { std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); int n, m, q; while (cin >> n >> m >> q) { for (int i = 0;i < q;i++) cin >> a[i]; memset(last, 0x7f, sizeof(last));///初始化下一位置无穷大,7f是最大,ff会变成负数 memset(vis, 0, sizeof(vis)); for (int i = q - 1;i >= 0;i--) {///倒序遍历,更新右侧最新位置 nxt[i] = last[a[i]];///第 i 个元素的下一个出现位置 last[a[i]] = i;///更新值为a[i]元素的最新位置 } priority_queue<pair<int, int>> pq; ///优先队列默认从大到小 int cnt = 0;///cnt代替内存使用长度,因为pq每次不管有没有都会插入,而pq长度并非真实长度 for (int i = 0;i < q;i++) { if (!vis[a[i]]) { if (cnt >= n) vis[a[pq.top().second]] = 0, pq.pop(); vis[a[i]] = 1; cnt++; } pq.push({ nxt[i],i });///持续插入,并不会导致反复删除同一个重复元素,因为如果出现重复元素一定从序列尾部的元素开始,等价于弹出了尾部元素,更新了到了前面 } cout << cnt << '\n'; } return 0; }
本文来自博客园,作者:空白菌,转载请注明原文链接:https://www.cnblogs.com/BlankYang/p/16460970.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧