首页 > 其他 > 详细

【bzoj3174】[Tjoi2013]拯救小矮人

时间:2017-02-15 15:11:18      阅读:223      评论:0      收藏:0      [点我收藏+]

题目描述

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

输入

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

输出

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

样例输入

样例1
2
20 10
5 5
30
样例2
2
20 10
5 5
35

样例输出

样例1
2
样例2
1


题解

贪心+dp

首先如果a.x+a.y<b.x+b.y(x、y分别为身高和手长),说明a的逃跑能力比b弱,应该先离开。如果不能离开,就待在下面。

然后按照这个dp即可。

f[i]表示逃出i人后人梯的最大高度。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5 struct data
 6 {
 7     int x , y;
 8 }a[2001];
 9 int f[2001];
10 bool cmp(data a , data b)
11 {
12     return a.x + a.y < b.x + b.y;
13 }
14 int main()
15 {
16     int n , i , j , h , ans = 0;
17     scanf("%d" , &n);
18     memset(f , -1 , sizeof(f));
19     f[0] = 0;
20     for(i = 1 ; i <= n ; i ++ )
21         scanf("%d%d" , &a[i].x , &a[i].y) , f[0] += a[i].x;
22     scanf("%d" , &h);
23     sort(a + 1 , a + n + 1 , cmp);
24     for(i = 1 ; i <= n ; i ++ )
25     {
26         for(j = ans ; j >= 0 ; j -- )
27             if(f[j] + a[i].y >= h)
28                 f[j + 1] = max(f[j + 1] , f[j] - a[i].x);
29         if(f[ans + 1] >= 0)
30             ans ++ ;
31     }
32     printf("%d\n" , ans);
33     return 0;
34 }

 

【bzoj3174】[Tjoi2013]拯救小矮人

原文:http://www.cnblogs.com/GXZlegend/p/6401325.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!