[TJOI2013]拯救小矮人

Posted StaroForgin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[TJOI2013]拯救小矮人相关的知识,希望对你有一定的参考价值。

拯救小矮人

题解

虽说是拯救小矮人这道题,但在模拟赛做的时候数据范围实际上开到了 n ⩽ 2 × 1 0 5 n\\leqslant 2\\times 10^5 n2×105,也就只能用贪心了。

首先对于一个人,如果它需要拉过来垫背的人的高度越高,那他肯定就越难走,如果他现在走不出去,那他以后也甭想走出去,所以我们可以先对所有人按 a i + b i a_{i}+b_{i} ai+bi从小到大排序。
排完序后如果我们枚举到的人现在就可以跑出去,那就让他跑出去。
否则,我们肯定还得拉一个人来给他垫背,很明显,垫背的人一定是越高越好,所以我们将已经跑出去的人中最高的一个拿来给他垫背,而垫背的人肯定就跑不出去了,因为这个人 a + b a+b a+b肯定比我们跑出去的人小,之前那个人之前都跑不出去,他肯定也跑不出去。
如果拉来人给他垫背他都跑不出去,那他这辈子也别想跑出去了,显然,我们不可能拉两个人来给他垫背。
如果他的高度比我们能拉来的所有人都高,那还不如就让他去垫背,不跑出去了,这样我们后面的人能用的高度才能竟可能的高。
事实上就这样贪心地跑过去就行了。

时间复杂度 O ( n l o g   n ) O\\left(nlog\\,n\\right) O(nlogn)

源码

#include<bits/stdc++.h>
using namespace std;
#define MAXN 200005
#define lowbit(x) (x&-x)
#define reg register
#define pb push_back
#define mkpr make_pair
#define fir first
#define sec second
typedef long long LL;
typedef unsigned long long uLL;
const LL INF=0x3f3f3f3f3f3f3f3f;
const int mo=998244353;
const int inv2=499122177;
const int jzm=2333;
const int zero=10000;
const int orG=3,invG=332748118;
const double Pi=acos(-1.0);
const double eps=1e-5;
typedef pair<int,int> pii;
template<typename _T>
_T Fabs(_T x){return x<0?-x:x;}
template<typename _T>
void read(_T &x){
	_T f=1;x=0;char s=getchar();
	while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}
	while('0'<=s&&s<='9'){x=(x<<3)+(x<<1)+(s^48);s=getchar();}
	x*=f;
}
template<typename _T>
void print(_T x){if(x<0){x=(~x)+1;putchar('-');}if(x>9)print(x/10);putchar(x%10+'0');}
LL gcd(LL a,LL b){return !b?a:gcd(b,a%b);}
int add(int x,int y,int p){return x+y<p?x+y:x+y-p;}
void Add(int &x,int y,int p){x=add(x,y,p);}
int qkpow(int a,int s,int p){int t=1;while(s){if(s&1LL)t=1ll*a*t%p;a=1ll*a*a%p;s>>=1LL;}return t;}
int n,H,ans;LL summ;
struct ming{int a,b;}s[MAXN]; 
bool cmp(ming x,ming y){return x.a+x.b<y.a+y.b;}
priority_queue<int>q;
signed main(){
	read(n);while(!q.empty())q.pop();
	for(int i=1;i<=n;i++)read(s[i].a),read(s[i].b),summ+=1ll*s[i].a;
	read(H);sort(s+1,s+n+1,cmp);
	for(int i=1;i<=n;i++)
		if(summ+s[i].b>=1ll*H)summ-=s[i].a,ans++,q.push(s[i].a);
		else if(!q.empty()&&q.top()>s[i].a&&q.top()+summ+s[i].b>=1ll*H)
			summ+=q.top()-s[i].a,q.pop(),q.push(s[i].a);
	printf("%d\\n",ans);
	return 0;
}

谢谢!!!

以上是关于[TJOI2013]拯救小矮人的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ_3174_[Tjoi2013]拯救小矮人_贪心+DP

[TJOI2013]拯救小矮人

[TJOI2013]拯救小矮人 nlogn贪心Hack征集

[TJOI2013]拯救小矮人[排序+dp]

bzoj3174: [Tjoi2013]拯救小矮人

BZOJ3174: [Tjoi2013]拯救小矮人