Operating System(堆,贪心)
原题链接
https://ac.nowcoder.com/acm/problem/15688
思路
如果内存没有满,很简单,直接将数放到内存中即可。问题在于慢了之后替换的时候替换内存中的哪一个数?这里的贪心思路是替换当前内存中下一次出现时间最晚的那个数,这可以用一个堆来维护,注意:如果当前的询问已经在堆中,也要将其插入堆中去更新下一次出现的时间,可以证明,两个值一样的数,新插入的这个下一次出现的时间一定大于上一次插入的那个。
代码
#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
typedef pair<int, int> PII;
const int N = 100010;
priority_queue<PII> heap;
int a[N];
bool st[N];
int n, m, q;
int ne[N], last[N];
void init()
{
while (heap.size()) heap.pop();
memset(last, 0x3f, sizeof last);
memset(st, false, sizeof st);
}
int main()
{
while (cin >> n >> m >> q)
{
init();
for (int i = 1; i <= q; i ++ ) cin >> a[i];
for (int i = q; i >= 1; i -- ) // 处理每个位置的点下一次在哪里出现
{
ne[i] = last[a[i]];
last[a[i]] = i;
}
int ans = 0;
for (int i = 1; i <= q; i ++ )
{
if (!st[a[i]]) // 如果当前的点没有在堆中
{
if (ans >= n) // 如果ans < n说明内存一定没有满,反之一定满了,内存时刻都保持满状态,需要替换
{
st[heap.top().second] = false;
heap.pop();
}
st[a[i]] = true;
ans ++ ;
}
heap.push({ne[i], a[i]});
}
cout << ans << endl;
}
return 0;
}
浙公网安备 33010602011771号