zoukankan      html  css  js  c++  java
  • codevs1054 地鼠游戏(贪心,优先队列)

    题目描述 Description

        王钢是一名学习成绩优异的学生,在平时的学习中,他总能利用一切时间认真高效地学习,他不但学习刻苦,而且善于经常总结、完善自己的学习方法,所以他总能在每次考试中得到优异的分数,这一切很大程度上是由于他是一个追求效率的人。

        但王钢也是一个喜欢玩的人,平时在学校学习他努力克制自己玩,可在星期天他却会抽一定的时间让自己玩一下,他的爸爸妈妈也比较信任他的学习能力和学习习惯,所以在星期天也不会象其他家长一样对他抓紧,而是允许他在星期天上午可以自由支配时间。

        地鼠游戏是一项需要反应速度和敏捷判断力的游戏。游戏开始时,会在地板上一下子冒出很多地鼠来,然后等你用榔头去敲击这些地鼠,每个地鼠被敲击后,将会增加相应的游戏分值。问题是这些地鼠不会傻傻地等你去敲击,它总会在冒出一会时间后又钻到地板下面去(而且再也不上来),每个地鼠冒出后停留的时间可能是不同的,而且每个地鼠被敲击后增加的游戏分值也可能是不同,为了胜出,游戏参与者就必须根据每个地鼠的特性,有选择地尽快敲击一些地鼠,使得总的得分最大。

    这个极具挑战性的游戏王钢特别喜欢,最近他经常在星期天上午玩这个游戏,慢慢地他不但敲击速度越来越快(敲击每个地鼠所需要的耗时是1秒),而且他还发现了游戏的一些特征,那就是每次游戏重新开始后,某个地鼠冒出来后停留的时间都是固定的,而且他记录了每个地鼠被敲击后将会增加的分值。于是,他在每次游戏开始后总能有次序地选择敲击不同的地鼠,保证每次得到最大的总分值。

    输入描述 Input Description

        输入包含3行,第一行包含一个整数n1<=n<=100)表示有n个地鼠从地上冒出来,第二行n个用空格分隔的整数表示每个地鼠冒出后停留的时间,第三行n个用空格分隔的整数表示每个地鼠被敲击后会增加的分值(<=100)。每行中第i个数都表示第i个地鼠的信息。

    输出描述 Output Description

        输出只有一行一个整数,表示王钢所能获得的最大游戏总分值。

    样例输入 Sample Input

    5

    5  3  6  1  4

    7  9  2  1  5

    样例输出 Sample Output

    24


    可以倒过来考虑,停留时间最长的一个肯定是要打的(如果多个则打分值最大的)。从后往前遍历每一个时间点,如果该时间点有能打的(包括这个点马上要缩回去和这个点之后才回去且没被打掉),那就从这些里面选一个价值最大的打。注意时间点是倒序枚举。对于这个“选价值最大的打”,我们可以用优先队列来实现,枚举的时候把符合条件的加进去,打的时候取队头的就好了。



    #include <map>
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <string>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <set>
    #include <time.h>
    using namespace std;
    const int maxn = 50005;
    #define rep(i,f,t) for(int i = (f),_end = (t); i <= _end; ++i)
    #define dep(i,f,t) for(int i = (f),_end = (t); i >= _end; ++i)
    #define debug(x) cout<<"debug "<<x<<endl;
    #define clr(c,x) memset(c,x,sizeof(c));
    pair<int,int> pr[110];
    int main() {
        int n;
        priority_queue<int> q;
        scanf("%d",&n);
        rep(i,1,n)scanf("%d",&pr[i].first);
        rep(i,1,n)scanf("%d",&pr[i].second);
        sort(pr+1,pr+n+1);
        int ans = 0;
        int t = pr[n].first;
        int i = n;
        for(; t > 0; --t){
            while(i > 0 && pr[i].first >= t)q.push(pr[i--].second);   //其实后面那个 >= 也可以写成 ==
            
            if(q.empty())continue;
            ans += q.top();
            q.pop();
        }
        printf("%d
    ",ans);
        return 0;
    }


    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    那些离不开的 Chrome 扩展插件
    Spring Boot 实战 —— 入门
    Maven 学习笔记
    Linux lvm 分区知识笔记
    Linux 双向 SSH 免密登录
    CentOS Yum 源搭建
    Ubuntu 系统学习
    iOS 测试三方 KIF 的那些事
    Swift 网络请求数据与解析
    iOS Plist 文件的 增 删 改
  • 原文地址:https://www.cnblogs.com/DSChan/p/4862007.html
Copyright © 2011-2022 走看看