BZOJ 1528 POI2005 sam-Toy Cars 堆+贪心

题目大意:有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;
}


你可能感兴趣的:(堆,贪心,bzoj,BZOJ1528)