BZOJ1826: [JSOI2010]缓存交换
2017-10-09 18:04
274 查看
1826: [JSOI2010]缓存交换
Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 783 Solved: 439
[Submit][Status][Discuss]
Description
在计算机中,CPU只能和高速缓存Cache直接交换数据。当所需的内存单元不在Cache中时,则需要从主存里把数据调入Cache。此时,如果Cache容量已满,则必须先从中删除一个。例如,当前Cache容量为3,且已经有编号为10和20的主存单元。
此时,CPU访问编号为10的主存单元,Cache命中。
接着,CPU访问编号为21的主存单元,那么只需将该主存单元移入Cache中,造成一次缺失(Cache Miss)。
接着,CPU访问编号为31的主存单元,则必须从Cache中换出一块,才能将编号为31的主存单元移入Cache,假设我们移出了编号为10的主存单元。
接着,CPU再次访问编号为10的主存单元,则又引起了一次缺失。我们看到,如果在上一次删除时,删除其他的单元,则可以避免本次访问的缺失。
在现代计算机中,往往采用LRU(最近最少使用)的算法来进行Cache调度——可是,从上一个例子就能看出,这并不是最优的算法。
对于一个固定容量的空Cache和连续的若干主存访问请求,聪聪想知道如何在每次Cache缺失时换出正确的主存单元,以达到最少的Cache缺失次数。
Input
输入文件第一行包含两个整数N和M(1<=M<=N<=100,000),分别代表了主存访问的次数和Cache的容量。第二行包含了N个空格分开的正整数,按访问请求先后顺序给出了每个主存块的编号(不超过1,000,000,000)。
Output
输出一行,为Cache缺失次数的最小值。Sample Input
6 21 2 3 1 2 3
Sample Output
4HINT
在第4次缺失时将3号单元换出Cache。Source
JSOI2010第二轮Contest2【题解】
每次选择下一个调用位置最远的交换出去
用堆实现,很多细节,见代码
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <map> #include <queue> #define max(a, b) ((a) > (b) ? (a) : (b)) #define min(a, b) ((a) < (b) ? (a) : (b)) inline void read(long long &x) { x = 0;char ch = getchar(), c = ch; while(ch < '0' || ch > '9')c = ch, ch = getchar(); while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar(); if(c == '-')x = -x; } const long long MAXN = 100000 + 10; long long n,m,num[MAXN],cnt[MAXN],nxt[MAXN],ans,chuxian[MAXN],sum; bool cmp(long long a, long long b) { return num[a] < num[b]; } struct cmpp { bool operator()(long long a, long long b) { return nxt[a] < nxt[b]; } }; std::priority_queue <int, std::vector<int>, cmpp> q; int main() { read(n), read(m); for(register long long i = 1;i <= n;++ i) read(num[i]), cnt[i] = i; std::sort(cnt + 1, cnt + 1 + n, cmp); long long tot = 1, pre = num[cnt[1]]; num[cnt[1]] = tot; for(register long long i = 2;i <= n;++ i) if(num[cnt[i]] == pre)num[cnt[i]] = tot; else ++ tot, pre = num[cnt[i]], num[cnt[i]] = tot; memset(cnt, 0, sizeof(cnt)); memset(nxt, 0x3f, sizeof(nxt)); for(register long long i = n;i >= 1;-- i) { if(cnt[num[i]])nxt[i] = cnt[num[i]]; cnt[num[i]] = i; } memset(cnt, 0, sizeof(cnt)); ///cnt[i]表示i这个数是否在堆中以及i在原数组中的位置,chuxian[i]表示原数组i元素是否在堆中 for(register long long i = 1;i <= n;++ i) { if(cnt[num[i]]) { q.push(i); chuxian[cnt[num[i]]] = 0; chuxian[i] = 1; } else { if(sum < m)q.push(i), cnt[num[i]] = i, chuxian[i] = 1, ++ans, ++sum; else { while(chuxian[q.top()] == 0)q.pop(); cnt[num[q.top()]] = 0; chuxian[q.top()] = 0; q.pop(); q.push(i); chuxian[i] = 1; cnt[num[i]] = i; ++ ans; } } } printf("%lld", ans); return 0; }
BZOJ1826
相关文章推荐
- [bzoj1826] [JSOI2010]缓存交换
- BZOJ 1826: [JSOI2010]缓存交换
- 【优先队列+贪心】BZOJ1826-[JSOI2010]缓存交换
- 【bzoj 1826&1528】: [JSOI2010]缓存交换
- bzoj 1826: [JSOI2010]缓存交换
- [BZOJ]1826: [JSOI2010]缓存交换 线段树
- bzoj1826: [JSOI2010]缓存交换
- BZOJ_1826_[JSOI2010]缓存交换 _线段树+贪心
- 【BZOJ】【P1826&P1528】【JSOI2010】【缓存交换】【题解】【堆+贪心】
- 1826: [JSOI2010]缓存交换
- 1826: [JSOI2010]缓存交换
- 1826: [JSOI2010]缓存交换
- 【贪心】【JSOI2010】缓存交换
- 【BZOJ1826】【tyvj2644】缓存交换,贪心+堆维护
- bzoj1826: [JSOI2010]缓存交换 贪心+优先队列
- BZOJ 1823 [JSOI2010]满汉全席 - 2-sat
- 【BZOJ1822】【JSOI2010】Frozen Nova 冷冻波
- 【bzoj 1821】 [JSOI2010]Group 部落划分 Group
- bzoj1820: [JSOI2010]Express Service 快递服务
- [BZOJ1823][JSOI2010]满汉全席(2-SAT)