题目大意:有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; }
时间: 2024-11-05 19:00:38