D. Contest Balloons(贪心详解)

想了几分钟就出思路了

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


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

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

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

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

q 中 的 人 气 球 都 比 我 多 q中的人气球都比我多 q

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

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

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

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

一直重复这个步骤

这样就覆盖了所有的可能

#include 
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

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; }

你可能感兴趣的:(CF1900)