【BZOJ 1528】 1528: [POI2005]sam-Toy Cars (贪心+堆)
1528: [POI2005]sam-Toy Cars
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
HINT
Source
【分析】
贪心很可以。记录下每个玩具下次出现的位置,每次要删的话选一个最远的删掉。用优先队列优化。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 #include<cmath> 7 #include<queue> 8 #include<vector> 9 using namespace std; 10 #define Maxn 500010 11 12 int a[Maxn],first[Maxn],nt[Maxn]; 13 bool mark[Maxn]; 14 15 struct node 16 { 17 int x,y; 18 friend bool operator < (node x,node y) 19 { 20 return x.x<y.x; 21 } 22 }; 23 24 priority_queue<node > q; 25 26 int main() 27 { 28 int n,k,p; 29 scanf("%d%d%d",&n,&k,&p); 30 for(int i=1;i<=p;i++) scanf("%d",&a[i]); 31 memset(first,0,sizeof(first)); 32 for(int i=p;i>=1;i--) 33 { 34 nt[i]=first[a[i]]; 35 first[a[i]]=i; 36 } 37 for(int i=1;i<=p;i++) if(nt[i]==0) nt[i]=p+1; 38 memset(mark,0,sizeof(mark)); 39 int cnt=0,ans=0; 40 while(!q.empty()) q.pop(); 41 for(int i=1;i<=p;i++) 42 { 43 if(!mark[a[i]]) 44 { 45 ans++; 46 if(cnt<k) cnt++; 47 else 48 { 49 node nw=q.top();q.pop(); 50 mark[nw.y]=0; 51 } 52 mark[a[i]]=1; 53 } 54 node now; 55 now.x=nt[i];now.y=a[i]; 56 q.push(now); 57 } 58 printf("%d\n",ans); 59 return 0; 60 }
2017-01-13 21:20:41