拯救小矮人 (test0725) bzoj3174 luogu4823
作者:互联网
3174: [Tjoi2013]拯救小矮人
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 1191 Solved: 685
[Submit][Status][Discuss]
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
样例12
20 10
5 5
30
样例2
2
20 10
5 5
35
Sample Output
样例12
样例2
1
HINT
数据范围
30%的数据 N<=200
100%的数据 N<=2000
一道比较好想的贪心+dp题,可能就我这样的傻逼理解错题意爆零
先想dp,dp[i][j]表示考虑到第i个人,逃出了j个人时小矮人能达到的最大高度
然后考虑小矮人逃生顺序,就可以背包转移了
这需要一个贪心:一个身高加手长为h的人(且称为A)在一个身高加手长为h-1的人(且称为B)前面出去不会特别好
假设A本来在B前面,交换位置
1.A的身高高于B的身高,那么交换后可以降低dp[i][]值下降的速度,后面会有更多的可能
2.A的身高低于B的身高,那么A的手长一定大于B的手长,由于dp[i][]值单调递减,因此A能出去的可能性更大
哎......感慨......为什么这么容易的题我也做不出呢.....
#include<bits/stdc++.h> using namespace std; const int N=4005; int n,H; struct person { int a,b; }p[N]; int dp[N][N]; bool cmp(person u,person v) {return u.a+u.b<v.a+v.b;} int main() { freopen("c.in","r",stdin); freopen("c.out","w",stdout); scanf("%d",&n); for(int i=1;i<=n;++i) scanf("%d%d",&p[i].a,&p[i].b); scanf("%d",&H); sort(p+1,p+n+1,cmp); memset(dp,0xcf,sizeof(dp)); dp[0][0]=0; for(int i=1;i<=n;++i) dp[0][0]+=p[i].a; for(int i=1;i<=n;++i) for(int j=0;j<=i;++j) { dp[i][j]=dp[i-1][j]; if(j>=1 && dp[i-1][j-1]+p[i].b>=H) dp[i][j]=max(dp[i-1][j-1]-p[i].a,dp[i][j]); } for(int i=n;i>=0;--i) if(dp[n][i]>=0) { printf("%d",i); return 0; } return 0; }
标签:luogu4823,int,bzoj3174,样例,小矮人,矮人,身高,dp 来源: https://www.cnblogs.com/w19567/p/11246933.html