题意:模拟OPT(最优页面置换算法),就是贪心。当需要换出页面的时候,选择cache中下一次访问时间最晚的页面换掉。
可以使用 set<int> 存储在cache中的页面,对每一个页号维护一个访问时间队列。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<map>
#include<algorithm>
#include<vector>
#include<queue>
#include<cstring>
#include<set>
#include<list>
using namespace std;
const int maxn = 100000;
const int inf = 0x7fffffff;
int C, N ,B;
int cnt[maxn+5];
typedef list<int> Array;
Array sd[maxn+5];
class CMP {
public:
bool operator () (int lhs, int rhs) const {
Array& v1 = sd[lhs];
Array& v2 = sd[rhs];
return v1.front() > v2.front();
}
};
int main() {
// freopen("input.in", "r", stdin);
while (cin >> C >> N >> B) {
for (int i=0;i<=N;++i) sd[i].clear();
vector<int> seq;
set<int, CMP> m;
for (int i=0;i<B;++i) {
int tmp;
cin >> tmp;
sd[tmp].push_back(i);
seq.push_back(tmp);
}
for (int i=0;i<N;++i) sd[i].push_back(inf);
//for (int i=0;i<B;++i) cout << seq[i] << ' ';cout << endl;
int ans = 0;
for (int i=0;i<B;++i) {
#if 0
cout << "set: ";
for (set<int>::iterator it=m.begin();it!=m.end();++it) {
cout << *it <<"(" << (sd[*it].front()) << ")" << ' ';
}
cout << endl;
#endif
int k = seq[i];
if (m.count(k)) {
m.erase(m.find(k));
sd[k].pop_front();
m.insert(k);
}
else {
++ans;
sd[k].pop_front();
if (m.size() >= C) {
int tmp = *(m.begin());
m.erase(m.begin());
//cout << "hi: " << tmp << endl;
}
m.insert(k);
}
}
cout << ans << endl;
}
return 0;
}