bzoj3174 [Tjoi2013]拯救小矮人

Description

一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯。即:一个小矮人站在另一小矮人的 肩膀上,知道最顶端的小矮人伸直胳膊可以碰到陷阱口。对于每一个小矮人,我们知道他从脚到肩膀的高度Ai,并且他的胳膊长度为Bi。陷阱深度为H。如果我 们利用矮人1,矮人2,矮人3,。。。矮人k搭一个梯子,满足A1+A2+A3+....+Ak+Bk>=H,那么矮人k就可以离开陷阱逃跑了,一 旦一个矮人逃跑了,他就不能再搭人梯了。
我们希望尽可能多的小矮人逃跑, 问最多可以使多少个小矮人逃跑。

Input

第一行一个整数N, 表示矮人的个数,接下来N行每一行两个整数Ai和Bi,最后一行是H。(Ai,Bi,H<=10^5)

Output

一个整数表示对多可以逃跑多少小矮人

Sample Input

样例1

2
20 10
5 5
30

样例2
2
20 10
5 5
35

Sample Output

样例1
2

样例2
1

HINT

数据范围

30%的数据 N<=200

100%的数据 N<=2000

首先orz hzwer

这题是贪心完dp

就是正常做法:已知两个相邻的小矮人a和b,考虑交换ab位置的代价

首先如果a在b下面,那么第一次的高度是a.a+b.a+b.b,第二次的高度是a.a+a.b

然后如果b在a下面,那么第一次的高度是a.a+b.a+a.b,第二次的高度是b.a+b.b

我们要考虑的就是交换ab会对原来的答案有什么影响

比较直观的想法是关键看第二次的高度,因为第二次的高度更高的那个,最终一定比另一个优。

还要考虑可能会出现的第二个比另一个更高但是第一个不如另一个的情况。

即可能出现a.a+a.b>b.a+b.b,但是a.a+b.a+b.b<a.a+b.a+a.b,即a.b>a.a+b.b。要知道这是完全可能的

考虑在这种情况下,假设a.b>a.a+b.b,那不交换的情况下第一次是a.a+b.a+b.b<a.b+b.a<b.b+a.b+a.a因此交换完还是更优

所以只需a.a+a.b<a.a+b.b即可

上面我们已经证明按贪心完的顺序取是最优的,但是还要确定最多能走掉多少个

接下来要dp:令f[i]表示走完i个矮人之后还能取到的最大高度

这样贪心的作用就出来了:按照贪心完的顺序取走矮人,可以保证最优。

一开始初始化f[0]表示没有矮人走掉,f[0]=Σa[i]。

然后就是枚举取到第i个矮人,可以用它来更新f[j]的情况是f[j]+ai.b>=m。

这样就可以算出最大值了

这题解真TM长……要把贪心讲清楚真不容易啊

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<deque>
#include<set>
#include<map>
#include<ctime>
#define LL long long
#define inf 0x7ffffff
#define pa pair<int,int>
#define pi 3.1415926535897932384626433832795028841971
using namespace std;
inline LL read()
{
    LL x=0,f=1;char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
    return x*f;
}
inline void write(LL a)
{
	if (a<0){printf("-");a=-a;}
	if (a>=10)write(a/10);
	putchar(a%10+‘0‘);
}
struct man{int a,b;}a[100010];
inline bool operator <(const man &a,const man &b)
{return a.a+a.b<b.a+b.b;}
int n,lim,ans;
int f[100010];
int main()
{
	memset(f,-1,sizeof(f));f[0]=0;
	n=read();
	for(int i=1;i<=n;i++)
	{
		a[i].a=read();a[i].b=read();
		f[0]+=a[i].a;
	}
	lim=read();
	sort(a+1,a+n+1);
	for (int i=1;i<=n;i++)
	{
		for (int j=ans;j>=0;j--)
		{
			if (a[i].b+f[j]>=lim)f[j+1]=max(f[j+1],f[j]-a[i].a);
			if (f[ans+1]>=0)ans++;
		}
	}
	write(ans);
	return 0;
}

  

时间: 2024-11-06 11:17:59

bzoj3174 [Tjoi2013]拯救小矮人的相关文章

[luogu] P4823 [TJOI2013]拯救小矮人(贪心)

P4823 [TJOI2013]拯救小矮人 题目描述 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀上,知道最顶端的小矮人伸直胳膊可以碰到陷阱口. 对于每一个小矮人,我们知道他从脚到肩膀的高度Ai,并且他的胳膊长度为Bi.陷阱深度为H. 如果我 们利用矮人1,矮人2,矮人3,...矮人k搭一个梯子,满足A1+A2+A3+....+Ak+Bk>=H,那么矮人k就可以离开陷阱逃跑了,一 旦一个矮人逃跑了,他就不能再搭人梯了. 我们希望

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

Description 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀上,知道最顶端的小矮人伸直胳膊可以碰到陷阱口.对于每一个小矮人,我们知道他从脚到肩膀的高度Ai,并且他的胳膊长度为Bi.陷阱深度为H.如果我 们利用矮人1,矮人2,矮人3,...矮人k搭一个梯子,满足A1+A2+A3+....+Ak+Bk>=H,那么矮人k就可以离开陷阱逃跑了,一 旦一个矮人逃跑了,他就不能再搭人梯了. 我们希望尽可能多的小矮人逃跑, 问最多可以

[TJOI2013]拯救小矮人

题目描述 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀上,知道最顶端的小矮人伸直胳膊可以碰到陷阱口. 对于每一个小矮人,我们知道他从脚到肩膀的高度Ai,并且他的胳膊长度为Bi.陷阱深度为H. 如果我 们利用矮人1,矮人2,矮人3,...矮人k搭一个梯子,满足A1+A2+A3+....+Ak+Bk>=H,那么矮人k就可以离开陷阱逃跑了,一 旦一个矮人逃跑了,他就不能再搭人梯了. 我们希望尽可能多的小矮人逃跑, 问最多可以使多少个小

[TJOI2013][BZOJ3174] 拯救小矮人

3174: [Tjoi2013]拯救小矮人 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 445  Solved: 217[Submit][Status][Discuss] Description 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀上,知道最顶端的小矮人伸直胳膊可以碰到陷阱口.对于每一个小矮人,我们知道他从脚到肩膀的高度Ai,并且他的胳膊长度为Bi.陷阱深度为H.如果我

[bzoj3174] 拯救小矮人

题意:N个小矮人被困在了一个高度为h的坑里,每个人都有一定的身高a_i和臂长b_i,小矮人可以站在别人的肩膀上,若a1+a2+...+ak+bk>=h,那么最上面的那个小矮人就可以逃跑,求怎样安排逃跑的顺序,使得尽量多的小矮人逃跑 题解: 贪心+dp 首先按身高加臂长sort(这种有两个代价的题是不是都是这个套路......,并不知道为什么......) 然后dp[i]表示i个人逃跑后剩下人的最大高度,这里好像不需要考虑臂长......,感性理解下就是下面的人越高,那么对上面的人贡献越大,所以出

拯救小矮人

思路: 贪心 + dp 首先贪心按身长加手长排序, 也就是让最难出去的先出去 但也有可能有人手短身子长, 那他奉献自己可能更优 所以在加个背包dp 代码: #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; const int N = 2005; const int H = 100500; int dp[H], n, h;

排队 (白雪公主与n个小矮人)

题目描述 [问题描述] 在七山七海之外的一个小村庄,白雪公主与N个矮人住在一起,所有时间都花在吃和玩League of Legend游戏.白雪公主决心终结这样的生活,所以为他们举办了体育课. 在每节课开始时,矮人必须按他们的身高站队.假定矮人们有高度1,2,...,N(每个人高度互不相同).然而,由于不健康的生活方式,矮人的智力有所恶化,所以他们没有能力依照自己的高度排序.    因此,白雪公主发出以下形式命令帮助他们:    1 X Y:X和Y位置的矮人互换位置.    2 A B:询问高度为

[codevs 1302] 小矮人(2002年CEOI中欧信息学奥赛)

描述 矮人们平时有走亲访友的习惯.一天,矮人国要修一条高速公路,矮人们希望他们走亲访友的时候,能够不必穿越高速公路,这样会更安全一些.现在有M个高速公路的修建方案,请你判断这M条高速功能是否能满足矮人们的期望.也就是说给出平面上的N个点(矮人们的住所位置),对于M条直线(高速公路),依次判断这N个点是否在每条直线的同一侧.是输出GOOD,不是输出BAD. 题解 首先可以想出一个凸包模型来,因为求出所有点的凸包后可以判断直线如果穿过凸包,就一定不满足题意. 问题是怎么判断直线是否穿过凸包呢? 如果

七个小矮人测试随笔

1.测试工作安排 项目 测试类型 测试结果 功能项 输入识别 功能项 四则运算 非功能项 界面及结果输出 原文地址:https://www.cnblogs.com/xjm123456/p/9980180.html