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;
}
posted on 2021-04-26 17:38  Laurance  阅读(107)  评论(0)    收藏  举报