打地鼠游戏(UPC5502)

题目描述

伟大的2320学长特别喜欢打地鼠游戏,这个游戏开始后,会在地板上冒出一些地鼠来,你可以用榔头去敲击这些地鼠,每个地鼠被敲击后,将会增加相应的游戏分值。可是,所有地鼠只会在地上出现一段时间(而且消失后再也不会出现),每个地鼠都在0时刻冒出,但停留的时间可能是不同的,而且每个地鼠被敲击后增加的游戏分值也可能是不同。
最近2320学长经常玩这个游戏,以至于敲击每个地鼠只要1秒。他在想如何敲击能使总分最大。

输入

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

输出

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

样例输入

5
5 3 6 1 4
7 9 2 1 5

样例输出

24

提示

30%的数据保证n<=100, t<=500,v<=50
60%的数据保证 n<=10000,t<=3000,v<=500
100%的数据保证 n<=100000,t<=5000,v<=1000

有n个地鼠,每个地鼠都在0时刻出来,但是每个地鼠存在时间不同,而且价值不同,每1秒可以打一个地鼠

问:最多可以获得多少价值

思路:先按照时间从小到大排序,相同时间按照价值从高到低排序,但是有时候会出现本时间出来多个价值非常高的地鼠,所以我们就要在前面替换,我们每次打的地鼠都放在队列里面,按照价值从低到高排序,如果出现没时间打的地鼠,先判断优先队列最小的(也就是第一个)是否更小,更小的话,就替换出去,获得的价值也相应变大,在T时间最多打T只地鼠,并且T时刻最多打一直地鼠,但是T时刻的地鼠可以在前面打,T时刻也可以打持续时间更长的其他地鼠,就是这个原因,所以我们可以使用优先队列来进行替换。在排序的时候需要使用运算符重载,注意不等号两边的数是本身结构体的变量还是另外一个结构体的变量,我就是因为这个错了十几遍,搞得越交越来气,哈哈。

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
const int maxn = 1e5 + 10;
struct Node
{
    int t, v;
    bool operator < (const Node& a) const
    {
        if(t == a.t)
        {
            return v > a.v;
        }
        return t < a.t;
    }
}p[maxn];
vector<int>ma[maxn];
priority_queue<int, vector<int>, greater<int> >q;
int main()
{
    int n;
    while(scanf("%d", &n) != EOF)
    {
        for(int i = 1; i < maxn; i++)
        {
            ma[i].clear();
        }
        int m = -1;
        for(int i = 1; i <= n; i++)
        {
            scanf("%d", &p[i].t);
            m = max(m, p[i].t);
        }
        for(int i = 1; i <= n; i++)
        {
            scanf("%d", &p[i].v);
        }
        sort(p+1, p+n+1);
        for(int i = 1; i <= n; i++)
        {
            ma[p[i].t].push_back(p[i].v);
        }
        while(!q.empty())
        {
            q.pop();
        }
        int ans = 0;
        for(int i = 1; i <= m; i++)
        {
            if(ma[i].size() != 0)
            {
                ans += ma[i][0];
                q.push(ma[i][0]);
            }
            else
            {
                q.push(0);
                continue;
            }
            for(int j = 1; j < ma[i].size(); j++)
            {
                if(ma[i][j] <= q.top())
                {
                    break;
                }
                else
                {
                    int temp = q.top();
                    q.pop();
                    ans -= temp;
                    ans += ma[i][j];
                    q.push(ma[i][j]);
                }
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/MALONG11124/article/details/81193072