堆+贪心——nkoj1587【Usaco Nov07 Gold】分配防晒霜

11 篇文章 0 订阅

【Usaco Nov07 Gold】分配防晒霜

Description

奶牛们计划着去海滩上享受日光浴。为了避免皮肤被阳光灼伤,所有C(1 <= C <= 2500)头奶牛必须在出门之前在身上抹防晒霜。第i头奶牛适合的最小和最大的SPF值分别为minSPF_i和maxSPF_i(1 <= minSPF_i <= 1,000; minSPF_i <= maxSPF_i <= 1,000)。如果某头奶牛涂的防晒霜的SPF值过小,那么阳光仍然能把她的皮肤灼伤;如果防晒霜的SPF值过大,则会使日光浴与躺在屋里睡觉变得几乎没有差别。 

为此,奶牛们准备了一大篮子防晒霜,一共L(1 <= L <= 2500)瓶。第i瓶防晒霜的SPF值为SPF_i(1 <= SPF_i <= 1,000)。瓶子的大小也不一定相同,第i瓶防晒霜可供cover_i头奶牛使用。当然,每头奶牛只能涂某一个瓶子里的防晒霜,而不能把若干个瓶里的混合着用。 

请你计算一下,如果使用奶牛们准备的防晒霜,最多有多少奶牛能在不被灼伤的前提下,享受到日光浴的效果?

Input

* 第1行: 2个用空格隔开的整数:C和L 
* 第2..C+1行: 第i+1行给出了适合第i头奶牛的SPF值的范围:minSPF_i以及maxSPF_i 
* 第C+2..C+L+1行: 第i+C+1行为了第i瓶防晒霜的参数:SPF_i和cover_i,两个数间用空格隔开。

Output

* 第1行: 输出1个整数,表示最多有多少头奶牛能享受到日光浴

Sample Input

3 2
3 10
2 5
1 5
6 2
4 1

Sample Output

2

Hint

输入说明: 
一共有3头奶牛,2瓶防晒霜。3头奶牛适应的SPF值分别为3..10,2..5,以及1..5。2瓶防晒霜的SPF值分别为6(可使用2次)和4(可使用1次)。可能的分配方案为:奶牛1使用第1瓶防晒霜,奶牛2或奶牛3使用第2瓶防晒霜。显然,最多只有2头奶牛的需求能被满足。

#include<cstdio>
#include<iostream>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
struct node
{
	int x;
	int y;
};
bool compare(node a,node b)//按照奶牛所需防晒值的最小值,防晒霜的防晒值进行升序排序 
{
	if(a.x==b.x)return a.y<b.y;
	return a.x<b.x;
}
node cow[2505],spf[2505];
priority_queue<int,vector<int>,greater<int> >q;
int main(){
	int c,l,i,j,k,ans=0;
	cin>>c>>l;
	for(i=1;i<=c;i++)
	{
		scanf("%d%d",&cow[i].x,&cow[i].y);
	}
	for(i=1;i<=l;i++)
	{
		scanf("%d%d",&spf[i].x,&spf[i].y);
	}
	sort(cow+1,cow+1+c,compare);
	sort(spf+1,spf+1+l,compare);
	int x=1,temp;
	for(i=1;i<=l;i++)
	{
		while(cow[x].x<=spf[i].x&&x<=c)//当前奶牛涂了防晒霜并不会被晒黑 
		{
			q.push(cow[x].y);
			x++;
		}
		while(spf[i].y>0&&q.size())
		{
			temp=q.top();
			if(temp>=spf[i].x)//如果cow.y大于防晒霜的防晒值,那么就给这只牛涂上防晒霜 
			{
				ans++;
				spf[i].y--;
			}//如果这只牛的y小于防晒值,那么后面的防晒霜的防晒值也会大于这只牛的y,所以这只牛就永远擦不到防晒霜了 
			q.pop();
		}
	}
	cout<<ans;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
题目描述 农夫约翰一直在观察他的奶牛们。他注意到,如果在牛群中有太多的牛靠得太近,就会导致不健康的行为和情感问题。 约翰想知道他的牛群是否存在这个问题。他定义这个问题为:在一个固定长度的路段上,如果有两头高度大于等于 $y$ 的奶牛之间的距离小于 $x$,则牛群中就存在一个挤得太近的情况。 约翰有 $N$ 头牛 ($1 \leq N \leq 50,000$),每头牛的高度为 $h_i$ ($1 \leq h_i \leq 1,000,000$)。他想知道是否存在一对牛,使得它们之间的距离小于 $x$,且它们的高度都大于等于 $y$。 输入格式 第一行包含三个整数 $N, L, R$,分别表示牛的数量,路段长度,和问题的最大高度。 接下来 $N$ 行,每行一个整数 $h_i$,表示每头牛的高度。 输出格式 如果存在一对牛,它们之间的距离小于 $x$,且它们的高度都大于等于 $y$,则输出 $1$,否则输出 $0$。 输入样例1 4 6 4 4 4 5 7 输出样例1 1 输入样例2 5 3 3 1 5 5 5 5 输出样例2 0 提示 对于 $30\%$ 的数据,$N \leq 500$。 对于 $100\%$ 的数据,$1 \leq N \leq 50,000$,$1 \leq L \leq 1,000,000$,且 $L \leq R$。 数据范围 时间限制:1.0s,空间限制:256MB 算法1 (暴力枚举) $O(n^2)$ 首先对输入的牛的高度进行排序,之后枚举每头牛,再枚举它后面的每头牛,如果两头牛的高度均大于等于 $y$,且它们之间的距离小于 $x$,则输出 $1$。如果最后仍然没有满足条件的牛,则输出 $0$。 时间复杂度 暴力枚举,时间复杂度为 $O(n^2)$,无法通过此题。 算法2 (滑动窗口) $O(n \log n)$ 为了方便后续操作,我们将所有的牛按照它们的高度从小到大排序。之后,我们维护一个长度为 $L$ 的滑动窗口,它的右端点与左端点之间的距离小于 $x$。我们从左到右扫描每头牛,将它加入滑动窗口的左端点,同时将滑动窗口右移,直到滑动窗口的右端点与左端点之间的距离小于 $x$。 在处理完一头牛之后,我们需要判断滑动窗口中是否存在一对牛,它们的高度均大于等于 $y$,且它们之间的距离小于 $x$。我们可以用双指针来实现这个操作。我们从滑动窗口的左端点开始,向右移动一个指针 $i$,同时向右移动一个指针 $j$,直到 $h_j - h_i \leq x$。在这个过程中,我们需要判断 $h_i$ 和 $h_j$ 是否均大于等于 $y$。如果存在一对牛满足条件,则输出 $1$。如果最后仍然没有满足条件的牛,则输出 $0$。 时间复杂度 因为需要对所有的牛进行排序,所以时间复杂度为 $O(n \log n)$。 C++ 代码 算法3 (暴力优化) $O(n \log n)$ 首先对输入的牛的高度进行排序,之后枚举每头牛。如果当前牛的高度小于 $y$,则跳过这头牛。否则,我们从它的左边和右边各扩展出一个长度为 $x$ 的区间。如果这两个区间内的牛的数量均大于等于 $2$,且这两个区间中任意两头牛的高度均大于等于 $y$,则输出 $1$。 时间复杂度 因为需要对所有的牛进行排序,所以时间复杂度为 $O(n \log n)$。 C++ 代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值