其他分享
首页 > 其他分享> > 拯救小矮人 (test0725) bzoj3174 luogu4823

拯救小矮人 (test0725) bzoj3174 luogu4823

作者:互联网

3174: [Tjoi2013]拯救小矮人

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 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

样例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

 

 

一道比较好想的贪心+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