3768 -- 【模拟试题】玩具车
Description
Jasio 是一个三岁的小男孩,他最喜欢玩玩具了,他有n 个不同的玩具,它们都被放在了很高的架子上,所以Jasio 拿不到它们。为了让他的房间有足够的空间,在任何时刻地板上都不会有超过k个玩具。
Jasio在地板上玩玩具。Jasio的妈妈则在房间里陪他的儿子,当Jasio 想玩地板上的其他玩具时,他会自己去拿,如果他想玩的玩具在架子上,他的妈妈则会帮他去拿,当她拿玩具的时候,顺便也会将一个地板上的玩具放上架子使得地板上有足够的空间。
他的妈妈很清楚自己的孩子,所以他能够预料到Jasio想玩些什么玩具。所以她想尽量的使自己去架子上拿玩具的次数尽量的少,应该怎么安排放玩具的顺序呢?
Input
输入文件的第一行三个整数:n, k, p (1<=k<=n <=100000, 1<=p<=500000),分别表示玩具的个数,地板上玩具的最多个数以及Jasio他想玩玩具的序列个数,接下来p行每行描述一个整数表示Jasio想玩的玩具编号。
Output
输出文件只有一行为一个整数,表示Jasio 的妈妈最少要拿多少次玩具。
Sample Input
3 2 7
1
2
3
1
3
1
2
Sample Output
4
Hint
【数据范围】
对于50%的数据1<=n<=500,1<=k<=200,1<=p<=2000
Description
Jasio 是一个三岁的小男孩,他最喜欢玩玩具了,他有n 个不同的玩具,它们都被放在了很高的架子上,所以Jasio 拿不到它们。为了让他的房间有足够的空间,在任何时刻地板上都不会有超过k个玩具。
Jasio在地板上玩玩具。Jasio的妈妈则在房间里陪他的儿子,当Jasio 想玩地板上的其他玩具时,他会自己去拿,如果他想玩的玩具在架子上,他的妈妈则会帮他去拿,当她拿玩具的时候,顺便也会将一个地板上的玩具放上架子使得地板上有足够的空间。
他的妈妈很清楚自己的孩子,所以他能够预料到Jasio想玩些什么玩具。所以她想尽量的使自己去架子上拿玩具的次数尽量的少,应该怎么安排放玩具的顺序呢?
Input
输入文件的第一行三个整数:n, k, p (1<=k<=n <=100000, 1<=p<=500000),分别表示玩具的个数,地板上玩具的最多个数以及Jasio他想玩玩具的序列个数,接下来p行每行描述一个整数表示Jasio想玩的玩具编号。
Output
输出文件只有一行为一个整数,表示Jasio 的妈妈最少要拿多少次玩具。
Sample Input
3 2 7
1
2
3
1
3
1
2
Sample Output
4
Hint
【数据范围】
对于50%的数据1<=n<=500,1<=k<=200,1<=p<=2000
对于100%的数据1<=n<=100000,1<=k<=100000,1<=p<=500000
贪心策略是个人都想得到吧..当空间不足时,删除下一个使用时间最晚的玩具..毕竟样例给得很清楚了。
那么这个就是明显的使用堆了,删除时取堆顶pop即可,当然记一个hash记录这个玩具在不在地板上。
然而写的时候WA了无数次..原因一是当发现地板上有这个玩具时,没有把新的next时间截给push进去,导致时间乱完了..
二是改正这个错误之后,一开始我只是单纯地把k个元素push进去,其实开始时必须要把地板铺满才能结束预处理,也即当hash[a[i]]=1的时候要记录再多入一个,不然k个push完后不一定能铺的满地板。
使用堆的时候注意每次pop无效数据。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<queue>
#define ll long long
#define pa pair<ll,ll>
using namespace std;
priority_queue<pa> Q;
inline ll read()
{
ll bj=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-')bj=-1;
ch=getchar();
}
ll ret=0;
while(ch>='0'&&ch<='9')ret=ret*10+ch-'0',ch=getchar();
return ret*bj;
}
ll n,k,p,a[1000005]={0},pos[1000005]={0},next[1000005]={0};
bool ha[1000005]={0};
void init()
{
n=read();k=read();p=read();
for(ll i=1;i<=p;i++)a[i]=read();
for(ll i=1;i<=p;i++)
{
if(!pos[a[i]]){pos[a[i]]=i;continue;}
else
{
next[pos[a[i]]]=i;
pos[a[i]]=i;
}
}
for(ll i=1;i<=p;i++)if(next[i]==0)next[i]=p+1;
}
void greed()
{
ll ans=0;
for(ll i=1;i<=k;i++)
{
if(ha[a[i]])
{
Q.push(make_pair(next[i],a[i]));
k++;
continue;
}
ans++;
Q.push(make_pair(next[i],a[i]));
ha[a[i]]=1;
}
for(ll i=1;i<=p;i++)
{
if(ha[a[i]])
{
Q.push(make_pair(next[i],a[i]));
continue;
}
while(!Q.empty()&&ha[Q.top().second]==0)Q.pop();
ha[Q.top().second]=0;
Q.pop();
Q.push(make_pair(next[i],a[i]));
ha[a[i]]=1;
ans++;
}
printf("%lld\n",ans);
}
int main()
{
init();
greed();
return 0;
}
/*
3 2 7
1
2
3
1
3
1
2
*/