bzoj1826: [JSOI2010]缓存交换

来源:互联网 发布:阿里云企业邮箱怎么样 编辑:程序博客网 时间:2024/06/05 11:52

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 2

1 2 3 1 2 3
Sample Output

4
HINT

在第4次缺失时将3号单元换出Cache。

水题

就是贪心地吧下一次出现的地方最远的删掉就好了
正确性显然

#include<cstdio>#include<cstdlib>#include<queue>#include<cstring>#include<algorithm>#include<iostream>using namespace std;const int N=100005;int n,m;int a[N];struct qq{    int id,x;}b[N];int next[N];//下一个是谁 struct qt{    int x;    bool operator < (qt a)const    {        return next[a.x]>next[x];    };};int ooo[N];bool cmp (qq a,qq b){return a.x<b.x;}bool in[N];//这个点在不在priority_queue<qt> q;int main(){    scanf("%d%d",&n,&m);    for (int u=1;u<=n;u++)    {        scanf("%d",&b[u].x);        b[u].id=u;    }    sort(b+1,b+1+n,cmp);    int last=0,cnt=0;    for (int u=1;u<=n;u++)    {        if (b[u].x!=last) cnt++;        a[b[u].id]=cnt;last=b[u].x;    }    memset(ooo,127,sizeof(ooo));    for (int u=n;u>=1;u--)    {        next[u]=ooo[a[u]];        ooo[a[u]]=u;    }//  for (int u=1;u<=n;u++) printf("%d ",a[u]);    /*printf("\n");    for (int u=1;u<=n;u++) printf("%d ",next[u]);*/    memset(in,false,sizeof(in));    int lalal=0;    int ans=0;    for (int u=1;u<=n;u++)    {        if (in[a[u]]==true)         {            q.push(qt{u});            continue;        }        if (lalal==m)        {            while (!q.empty())            {                int hh=(q.top()).x;q.pop();                if (in[a[hh]]==true)                {                    in[a[hh]]=false;                    break;                }            }        }        else lalal++;        in[a[u]]=true;        ans++;q.push(qt{u});    }    printf("%d\n",ans);    return 0;}
原创粉丝点击