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;
}
时间: 2024-11-05 19:00:38

BZOJ 1528 POI2005 sam-Toy Cars 堆+贪心的相关文章

BZOJ 1150 CTSC2007 数据备份Backup 堆+贪心

题目大意:给定一个长度为n?1的序列,要求选出k个不相邻的数使得和最小 费用流显然能跑,而且显然过不去- - 考虑用堆模拟费用流 一个错误的贪心是每次取最小,这样显然过不去样例 我们把[每次取最小]改为[每次选择一个区间取反],用堆来维护这些区间即可 每次取出最小的区间,然后将两边合并 (比如现在堆里有[1,3][4,4][5,5])这三个区间,我取走了[4,4]并计入答案,那么我删除[1,3]和[5,5]这两个区间,并加入[1,5]这个区间,权值为[1,3]的权值+[5,5]的权值-[4,4]

【BZOJ 1528】 1528: [POI2005]sam-Toy Cars (贪心+堆)

1528: [POI2005]sam-Toy Cars Description Jasio 是一个三岁的小男孩,他最喜欢玩玩具了,他有n 个不同的玩具,它们都被放在了很高的架子上所以Jasio 拿不到它们. 为了让他的房间有足够的空间,在任何时刻地板上都不会有超过k 个玩具. Jasio 在地板上玩玩具. Jasio'的妈妈则在房间里陪他的儿子. 当Jasio 想玩地板上的其他玩具时,他会自己去拿,如果他想玩的玩具在架子上,他的妈妈则会帮他去拿,当她拿玩具的时候,顺便也会将一个地板上的玩具放上架

水题 Codeforces Round #303 (Div. 2) A. Toy Cars

题目传送门 1 /* 2 题意:5种情况对应对应第i或j辆车翻了没 3 水题:其实就看对角线的上半边就可以了,vis判断,可惜WA了一次 4 3: if both cars turned over during the collision. 5 是指i,j两辆车,而不是全部 6 */ 7 #include <cstdio> 8 #include <algorithm> 9 #include <cstring> 10 #include <cmath> 11 #

BZOJ 1010 玩具装箱toy(四边形不等式优化DP)(HNOI 2008)

Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1...N的N件玩具,第i件玩具经过压缩后变成一维长度为Ci.为了方便整理,P教授要求在一个一维容器中的玩具编号是连续的.同时如果一个一维容器中有多个玩具,那么两件玩具之间要加入一个单位长度的填充物,形式地说如果将第i件玩具到第j个玩具放到一个容器中,那么容器的长度将为 x=j-i+Sigma(Ck) i<

POJ3253 Fence Repair 小顶堆+贪心

给了你N个木棒,求把他们组装成一根需要的最小花费,每次只能选两根组装在一起,需要的花费为两个木棒之和, 以前遇到过把一整根切开的,那个是DP,这个则有些类似,可是大胆的猜测了一下,直接每次选取所有木棒中最短的两根,这样就可以了,那么贪心是适用的,但是数量很多,而且两根最短的组装好了得插回去,这样不可能每次都排序吧, 这题首先优先队列肯定是可以做的, 最小堆也是可以的,每次都选出堆里的最小的两个求和再放回去即可 队列本身也就是堆吧,所以差别不大,但是没用过最小堆最大堆的 所以用一次把 #inclu

P4053 [JSOI2007]建筑抢修 堆贪心

思路:堆贪心 提交:1次 题解: 先按时间\(sort\),然后如果能修就直接扔堆里,不能修取堆顶比一下时间长短,把时间短的扔进堆: #include<cstdio> #include<iostream> #include<queue> #include<algorithm> #define ull unsigned long long #define ll long long #define R register int using namespace s

BZOJ 1229 [USACO2008 Nov]toy 玩具(三分+贪心)

[题木链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1229 [题目大意] 每天对玩具都有一定的需求ni,每天可以花f价值每条购买玩具, 当天用完的玩具可以花费fA价值每个通过快消毒在A天之后得到一条可用的, 也可以通过花费fB价值每个,通过慢消毒在B天之后获得可用的 问满足每天需求所用的最小花费. [题解] 这是纸巾问题的费用流模型,费用流做法见 BZOJ 1221 [HNOI2001] 软件开发 但是我们发现N=100000的规模完全

BZOJ 2802 Poi2012 Warehouse Store 堆+贪心

题目大意:有n天,早上进货中午卖,可以选择卖或者不卖,问最多可以卖出多少人 首先贪心的思想是如果当前能卖就卖 但是这样不一定是最优的 比如说我第一天来一个人把所有的库存都买走了 然后后面基本没有补给 后面的人都饿死了 因此我们维护一个大根堆来记录我们都卖出了多少份 如果有一个人买不到 我们去大根堆里寻找有没有买的比他多的 如果有 把之前的人取消 卖给这个人 这样虽然不能增加答案 但是可以增加库存 #include <cstdio> #include <cstring> #inclu

BZOJ 1029: [JSOI2007]建筑抢修 堆+贪心

1029: [JSOI2007]建筑抢修 Description 小刚在玩JSOI提供的一个称之为“建筑抢修”的电脑游戏:经过了一场激烈的战斗,T部落消灭了所有z部落的入侵者.但是T部落的基地里已经有N个建筑设施受到了严重的损伤,如果不尽快修复的话,这些建筑设施将会完全毁坏.现在的情况是:T部落基地里只有一个修理工人,虽然他能瞬间到达任何一个建筑,但是修复每个建筑都需要一定的时间.同时,修理工人修理完一个建筑才能修理下一个建筑,不能同时修理多个建筑.如果某个建筑在一段时间之内没有完全修理完毕,这