• BZOJ 1528: [POI2005]sam-Toy Cars、BZOJ 1826: [JSOI2010]缓存交换


    1528: [POI2005]sam-Toy Cars

    Description

    Jasio 是一个三岁的小男孩,他最喜欢玩玩具了,他有n 个不同的玩具,它们都被放在了很高的架子上所以Jasio 拿不到它们. 为了让他的房间有足够的空间,在任何时刻地板上都不会有超过k 个玩具. Jasio 在地板上玩玩具. Jasio'的妈妈则在房间里陪他的儿子. 当Jasio 想玩地板上的其他玩具时,他会自己去拿,如果他想玩的玩具在架子上,他的妈妈则会帮他去拿,当她拿玩具的时候,顺便也会将一个地板上的玩具放上架子使得地板上有足够的空间. 他的妈妈很清楚自己的孩子所以他能够预料到Jasio 想玩些什么玩具. 所以她想尽量的使自己去架子上拿玩具的次数尽量的少,应该怎么安排放玩具的顺序呢?

    Input

    第一行三个整数: n, k, p (1 <= k <= n <= 100.000, 1 <= p <= 500.000), 分别表示玩具的总数,地板上玩具的最多个数以及Jasio 他想玩玩具的序列的个数,接下来p行每行描述一个玩具编号表示Jasio 想玩的玩具.

    Output

    一个数表示Jasio 的妈妈最少要拿多少次玩具.

    Sample Input

    3 2 7
    1
    2
    3
    1
    3
    1
    2

    Sample Output

    4

    思路:

      贪心,每当要把玩具放回去的时候放一个距离当前最远的,正确性显然,1826只需要对a数组进行离散化,思路一样;

    代码如下:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #include <iostream>
    #include <cctype>
    using namespace std;
    inline char nc() {
        static char buf[100000], *p1, *p2;
        return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
    }
    inline int read() {
        int x=0;char ch=nc();
        while(!isdigit(ch))ch=nc();
        while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=nc();}
        return x;
    }
    struct node {
        int next,x;
        bool operator < (const node &x) const {
            return next<x.next;
        }
    };
    int head[510000],a[510000],next[510000];
    bool vis[510000];
    priority_queue<node>q;
    int main() {
        /*freopen("toy.in","r",stdin);
        freopen("toy.out","w",stdout);*/
        int n,k,p;
        n=read(),k=read(),p=read();
        for(int i=1;i<=p;i++)a[i]=read();
        for(int i=1;i<=n;i++)head[i]=p+1;
        for(int i=1;i<=p;i++)
        {
            next[head[a[i]]]=i;
            head[a[i]]=i;
        }
        int now=0,ans=0;
        for(int i=1;i<=p;i++) if(!next[i])next[i]=p+1;
        for(int i=1;i<=p;i++) {
            if(vis[a[i]]) {
                node tmp;
                tmp.x=a[i];
                tmp.next=next[i];
                q.push(tmp);
            }
            else if(now<k) {
                now++;
                node tmp;
                tmp.x=a[i];
                tmp.next=next[i];
                q.push(tmp);
                vis[a[i]]=1;
                ans++;
            }
            else {
                node tmp=q.top();
                while(!vis[tmp.x]) {
                    //q.pop();
                    tmp=q.top();
                }
                q.pop();
                vis[tmp.x]=0;
                tmp.x=a[i];
                tmp.next=next[i];
                ans++;
                q.push(tmp);
                vis[a[i]]=1;
            }
        }
        printf("%d
    ",ans);
     
    }
    

     欢迎来原博客看看 >原文链接<

  • 相关阅读:
    HTML(图像img、表格table、列表)
    HTML(标题h、段落p、文本格式化、链接a、头部head)
    List的复制 (浅拷贝与深拷贝)
    最新CentOS6.5安装Docker, 使用阿里云源下载(亲测)
    VirtualBox安装CentOS6.5
    P1010 幂次方 题解
    P1469 找筷子 题解
    P1866 编号 题解
    EasyNVR通道离线但视频流可正常播放是什么原因导致的?
    EasyNVR通过国标GB28181协议级联出现报错及播放不了的问题调整
  • 原文地址:https://www.cnblogs.com/Tobichi/p/9084866.html
Copyright © 2020-2023  润新知