zoukankan      html  css  js  c++  java
  • noip2018模拟题(类背包+贪心)

    1. 马拉松冰球赛

    (marathon.pas/c/cpp)

    马拉松冰球锦标赛的日子就要到了。正如马拉松冰球比赛中经常出现的那样,比赛时间 M 分钟。和常规的冰球比赛一样,在每一给定时刻,场上两队各有 6 球员。然而,一场马拉松冰球比赛可以持续很长时间,所以教练带了一群球员,这样当球员们累了的时候,   他们可以进行替换。

    其中一个名为 Ante 的教练是我们故事的主角。Ante 带了 N 个球员参加比赛。对于每一个球员,他知道两个参数:球员的能力值 K 和耐力值 I耐力值是指球员参赛的最大总时间。假设一个球员先参加 X 分钟,然后休息,再参加 Y 分钟,他的总参赛时间就是 X+Y。当一个球员的总参赛时间等于其耐力值的时候,他就会感到疲惫,不能继续参赛,所以这个时候,   就需要其他人来代替他,否则他会晕倒在赛场上,最终被送进医院(马拉松冰球是一个危险的项目)。

    在一个给定时刻,队伍的能力值就是当前参赛队员能力值的总和。Ante 并不是一个伟大的教练,所以他要求你拿出最初的六名球员和替补球员的方案,以便他能达到每个时刻队   伍能力值总和的可能的最大值 Z。保证一定能找到一种方案,使得每个时刻场上都有 6 名球员。

    举个例子,假设比赛时间为 3 分钟,而第一分钟队伍的能力值是 15,第二分钟队伍的能力值是 12,第三分钟队伍的能力值是 14Z 就等于 15+12+14=41

    请注意:在马拉松冰球赛中是没有守门员的,因为比赛必须有趣。

    【输入】

    第一行输入两个正整数 M N(1≤M≤500 000,6≤N≤500000),分别表示比赛的持续时间(以分钟为单位),和 Ante 带领的球员数量。

    接下来 N 行,每行两个正整数 K I(1≤K≤100 000,1≤I≤M),表示每个球员的能力值和耐力值。

    球员按照输入顺序,从 1 N 编号。

    【输出】

    第一行包含题目要求的可能的最大值 Z

    【输入输出样例】

    200 6

    6600

    3 200

     

    4 200

     

    5 200

     

    6 200

     

    7 200

     

    8 200

     

    9 9

    1260

    10 3

     

    9 3

     

    13 9

     

    5 3

    15 9

    100 9

    3 6

    2 6

    1 6

    3 9

    1610

    100 3

     

    100 3

     

    100 3

     

    100 3

     

    100 2

     

    100 1

     

    50 1

     

    30 2

     

    1 1

     

    这道题虽然是一道比较水的题目

    但是也然我认识到一些比较重要的东西

    如背包能求出最优值,而一些贪心则会导致算法错误

    比如这道题,若直接贪心,那么就会导致一些值大的运动员无法得到足够时间发挥,

    但是用背包思想处理的话,就不会产生此类情况,因为用容量减,就不会出现一些选手得不到全部时间发挥

    背包会自我调控到能替代的运动员后面替换之

    所以以后遇到类似题目,一定学会转换思想,换成背包试试

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    
    typedef long long ll;
    
    const int maxn=500000+10;
    
    struct my{
           ll k,I;
    };
    
    my a[maxn];
    
    bool cmp(const my &x,const my &y){
         return x.k>y.k;
    }
    
    int main(){
        ll n,m;
        ll ans=0;
        scanf("%lld%lld",&m,&n);
        for (int i=1;i<=n;i++){
            scanf("%lld%lld",&a[i].k,&a[i].I);
        }
        int p=0;
        sort(a+1,a+1+n,cmp);
        m*=6;
        for (int i=1;i<=n;i++){
            if(m-a[i].I>=0){
                m-=a[i].I;
                ans+=(a[i].k*a[i].I);
            }
            else if(m>0) {
                m=0;
                ans+=(m*a[i].k);break;
            }
        }
        printf("%lld",ans);
    return 0;
    }
  • 相关阅读:
    正则表达式判断手机号是否11位
    php-流程管理(发起流程和审核流程)
    php-流程管理(新建流程)(php+Ajax)
    php-人员权限管理(RBAC)
    状态压缩DP
    树形DP
    Broken Keyboard UVA 11988 数组实现链表
    Trees in a Wood UVA
    POJ1061 青蛙的约会 拓展欧几里得
    UVA10215The Largest/Smallest Box(小数精度)
  • 原文地址:https://www.cnblogs.com/lmjer/p/9470859.html
Copyright © 2011-2022 走看看