D. Contest Balloons(贪心详解)

想了几分钟就出思路了

当然也不是说这题水,但我就是莫名的思路清晰hh?


开始肯定想到二分给的气球数,但是答案没有单调性

那么这么大的范围,就只有贪心了!!

, 使 名次想前进,就必须给气球给前面的使他们漂浮起来

( w t ) q 我们维护一个按照(w-t)小优先级大的优先队列q

q q中的人气球都比我多

假如我只让前面的一个人漂浮起来,那么我肯定选择那个 ( w t ) (w-t) 最小的人

q , , 从q中取出一个代价最小的人,给他气球,让他漂浮

但是此时我的气球减少了,所以有新的一些人比我气球多了,加入优先队列

此时优先队列的元素+1就是我的排名

一直重复这个步骤

这样就覆盖了所有的可能

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=3e5+10;
int ans,n,top;
struct p{
	int t,w,cha;
	bool operator < (const p&tmp )	const{
		return cha>tmp.cha;//差值小的优先级高 
	}
}xiao[maxn],chu;
priority_queue<p>q;
bool com(p a,p b){
	return a.t>b.t;
} 
signed main()
{
	cin >> n;
	cin >> chu.t >> chu.w;
	for(int i=2;i<=n;i++)
	{
		p temp;
		cin >> temp.t >> temp.w;
		temp.cha=temp.w-temp.t+1;//需要比w还多一个气球才可以漂浮 
		if( temp.t>chu.t )	q.push( temp ),ans++;
		else	xiao[++top]=temp; 
	}
	sort(xiao+1,xiao+1+top,com);
	//现在q装的是比自己大的,xiao里面装的是比自己小的
	int last=1;
	while( !q.empty() )
	{
		p u=q.top(); q.pop();//此时u为差值最小的 
		if( u.cha>chu.t )	break;//已经不足再使别人漂浮了
		chu.t-=u.cha;
		for(int i=last;i<=top;i++)
		{
			if( xiao[i].t>chu.t )	q.push( xiao[i] ),last++;
			else	break;	
		} 
		int siz=q.size();
		ans=min(ans,siz );
	} 
	cout << ans+1;
}

猜你喜欢

转载自blog.csdn.net/jziwjxjd/article/details/107880446