zoukankan      html  css  js  c++  java
  • 【bzoj3174】[Tjoi2013]拯救小矮人 贪心+dp

    题目描述

    一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯。即:一个小矮人站在另一小矮人的 肩膀上,知道最顶端的小矮人伸直胳膊可以碰到陷阱口。对于每一个小矮人,我们知道他从脚到肩膀的高度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人后人梯的最大高度。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    struct data
    {
        int x , y;
    }a[2001];
    int f[2001];
    bool cmp(data a , data b)
    {
        return a.x + a.y < b.x + b.y;
    }
    int main()
    {
        int n , i , j , h , ans = 0;
        scanf("%d" , &n);
        memset(f , -1 , sizeof(f));
        f[0] = 0;
        for(i = 1 ; i <= n ; i ++ )
            scanf("%d%d" , &a[i].x , &a[i].y) , f[0] += a[i].x;
        scanf("%d" , &h);
        sort(a + 1 , a + n + 1 , cmp);
        for(i = 1 ; i <= n ; i ++ )
        {
            for(j = ans ; j >= 0 ; j -- )
                if(f[j] + a[i].y >= h)
                    f[j + 1] = max(f[j + 1] , f[j] - a[i].x);
            if(f[ans + 1] >= 0)
                ans ++ ;
        }
        printf("%d
    " , ans);
        return 0;
    }
  • 相关阅读:
    如何挑选牙膏--2019/10/20
    怎样选卫生纸-2019/10/20
    页面动态加入<script>标签并执行代码
    ss 各种浏览器兼容前缀写法
    nth-child(n)、first-child、last-child用法
    改变checkbox的默认样式
    border和outline的区别
    标签嵌套规则和注意事项
    物理尺寸 转换为 像素
    打印iframe内容
  • 原文地址:https://www.cnblogs.com/GXZlegend/p/6401325.html
Copyright © 2011-2022 走看看