您的位置:首页 > 其它

[bzoj1528/POI2005]sam-Toy Cars---贪心+堆

2017-09-21 15:37 169 查看

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

分析

看似无从下手,实际上就是贪心:

第k天后,当要去上面拿玩具时,顺便带走下一次位置最远的(后者以后用不到的)即可。至于实现,用堆维护吧

代码

#include <cstdio>
#include <cstdlib>
#include <queue>
#define open(s) freopen(s".in","r",stdin); freopen(s".out","w",stdout);
#define close fclose(stdin); fclose(stdout);

using namespace std;

struct node
{
int p;//玩具编号
int w;//下一次的位置
bool operator < (const node &b) const
{
return w<b.w;//大根堆
}
};

int a[5000005];
int next
cf5c
[1000005];//下一次位置
int head[1000005];//辅助记录(可无视)
bool floor[1000005];//是否需要拿(在地板上)

int n,k,p;

inline int read()
{
int k=1;
int sum=0;
char c=getchar();
for(;'0'>c || c>'9' ;c=getchar())
if(c=='-') k=-1;
for(;'0'<=c && c<='9';c=getchar())
sum=sum*10+c-'0';
return sum*k;
}

inline void write(int x)
{
if(x<0) { putchar('-'); x*=-1; }
if(x>9) write(x/10);
putchar(x%10+'0');
}

int main()
{
open("sam");

n=read(); k=read(); p=read();
for(int i=1;i<=p;++i)
{
a[i]=read();
if(head[a[i]]) next[head[a[i]]]=i;
head[a[i]]=i;//类似前向星
}
for(int i=1;i<=p;++i)
if(!next[i]) next[i]=p+1;//最后一个的下一个赋值
int ans=0;
priority_queue<node>q;
for(int i=1;i<=p;++i)
{
if(floor[a[i]]) { q.push((node){a[i],next[i]}); continue ;  }//如果在地板上的话,入堆直接跳过
if(k)//如果没有超限,直接拿
{
q.push((node){a[i],next[i]});
floor[a[i]]=1;
--k; ++ans;
}else
{
for(;!floor[q.top().p];) q.pop();//不在地板上,跳过
floor[q.top().p]=0;//带走一个
q.pop();
q.push((node){a[i],next[i]});//加入一个
floor[a[i]]=1;
++ans;
}
}
write(ans);
close;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: