zoukankan      html  css  js  c++  java
  • P3419 [POI2005]SAMToy Cars / SP688 SAM Toy Cars

    一道很妙的贪心题

    题面

    我们考虑当我们插入时会面临的两种情况

    1. 当地上的玩具,不满 \(k\) 个时,那我们直接放就可以了。

    2. 当满了 \(k\) 个的时候,我们就要从地上拿出一个来给当前的腾位置。

      这就需要我们替换一个,根据我们贪心的思想,当一种玩具出现的比较晚

      的时候,那么我们就可以把它拿走,因为他后面用的次数比较少,这样妈妈

      的移动次数就会少很多 。

    那么,我们就有了处理这道题的思路,先求出每个点,他下一次要玩的时间

    \(net_i\) 用堆来维护地板上玩具 \(net_i\) 的最大值,来维护上述过程。

    坑点

    1. 多测数据一定要清空,最后不要忘记把堆清空

    2. 如果当前这个玩具后面都不会在玩它,我们应该把他的 \(net_i\)
      数组设为一个极大值,而不是0

    3. 如果当前这个点已经在地板上,我们依旧要把它入队,来代替之前的那个玩具。(我在这里卡了好长时间)

    Code

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<queue>
    #include<cstring>
    using namespace std;
    int t,n,k,p,ans,a[500010],last[500010],net[500010];
    bool used[100010];
    inline int read()
    {
    	int s = 0,w = 1; char ch = getchar();
    	while(ch < '0' || ch > '9'){if(ch == '-') w = -1; ch = getchar();}
    	while(ch >= '0' && ch <= '9'){s =s * 10+ch - '0'; ch = getchar();}
    	return s * w;
    }
    priority_queue<pair<int,int> >q;
    int main()
    {
    	t = read();
    	while(t--)
    	{
    		memset(last,0,sizeof(last)); memset(used,0,sizeof(used)); //多组数据一定要清空
    		n = read(); k = read(); p = read(); ans = 0;
    		for(int i = 1; i <= p; i++) a[i] = read();
    		for(int i = p; i >= 1; i--)
    		{
    			if(last[a[i]] == 0) net[i] = 2333333;//如果后面不会在玩这个玩具,我们要把他的 net[i] 数组设为极大值
    			else net[i] = last[a[i]];
    			last[a[i]] = i;
    		}
    		for(int i = 1; i <= p; i++)
    		{
    			if(used[a[i]])
    			{
    				k++;//如果这种玩具已经在地板上,我们要把他入队来替代之前不优的
    				q.push(make_pair(net[i],i));
    			}
    			else
    			{
    				if(q.size() < k)//Case1
    				{
    					q.push(make_pair(net[i],i));
    					used[a[i]] = 1; ans++;
    				}
    				else//Case2
    				{
    					int t = q.top().second; q.pop();
    					used[a[t]] = 0; used[a[i]] = 1; ans++;
    					q.push(make_pair(net[i],i));
    				}
    			}
    		}
    		printf("%d\n",ans);
    		while(!q.empty()) q.pop();//最后记得把堆清空
    	}
    	return 0;
    }
    

    另外,此题还有双倍经验 QAQ。

  • 相关阅读:
    python语法基础-常用模块-re模块
    python语法基础-常用模块-长期维护
    python语法基础-函数-内置函数和匿名函数-长期维护
    python语法基础-函数-递归函数-长期维护
    python语法基础-函数-迭代器和生成器-长期维护
    python语法基础-函数-装饰器-长期维护
    python语法基础-函数-进阶-长期维护
    python语法基础-函数-基础-长期维护
    Python之路--目录
    mysql数据库-索引-长期维护
  • 原文地址:https://www.cnblogs.com/genshy/p/13531789.html
Copyright © 2011-2022 走看看