题目大意:有n个玩具,都放在架子上,地板上能放k个,要玩p次玩具,如果不在地板上就要去架子上拿,地板满了要放回去,求最少操作次数
贪心思想:每次放回玩具时选择下次玩的时间最靠后的玩具放回去
可以用堆来模拟这一贪心过程
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 500500
using namespace std;
typedef pair<int,int> abcd;
int n,k,p,cnt,ans;
int a[M],last[100100],next[M];
bool on_floor[100100];
namespace Priority_Queue{
abcd heap[M];int top;
void Insert(abcd x)
{
heap[++top]=x;
int t=top;
while(t>1)
{
if(heap[t]>heap[t>>1])
swap(heap[t],heap[t>>1]),t>>=1;
else
break;
}
}
void Pop()
{
heap[1]=heap[top--];
int t=2;
while(t<=top)
{
if(t<top&&heap[t+1]>heap[t])
++t;
if(heap[t]>heap[t>>1])
swap(heap[t],heap[t>>1]),t<<=1;
else
break;
}
}
}
int main()
{
int i;
cin>>n>>k>>p;
for(i=1;i<=p;i++)
{
scanf("%d",&a[i]);
if(last[a[i]]) next[last[a[i]]]=i;
last[a[i]]=i;
}
for(i=1;i<=n;i++)
if(last[i])
next[last[i]]=0x3f3f3f3f;
for(i=1;i<=p;i++)
{
if(on_floor[a[i]])
{
Priority_Queue::Insert(abcd(next[i],a[i]));
continue;
}
if(cnt==k)
{
on_floor[Priority_Queue::heap[1].second]=0;
Priority_Queue::Pop();--cnt;
}
Priority_Queue::Insert(abcd(next[i],a[i]));
on_floor[a[i]]=1;++ans;++cnt;
}
cout<<ans<<endl;
return 0;
}