P2695 骑士的工作 题解

旅行传送门:快来点我鸭

题目背景
你作为一个村的村长,保卫村庄是理所当然的了.今天,村庄里来了一只恶龙,他有n个头,恶龙到处杀人放火。你着急了。不过天无绝人之路,现在来了一个骑士团。里面有m位成员(往下看)

题目描述
每个人都可以砍掉一个大小不超过(<=)z的头,要money个金币,求最小花费。

输入格式
第一行两个整数 n m

下接n行,一个整数 表示n个头的大小。

下接m行,每个人可以砍的头大小或金币(金币==头的大小)。

输出格式
一个整数,最小花费。如果无解,输出“you died!”

输入输出样例
输入 #1复制
2 3
5
4
7
8
4
输出 #1复制
11
说明/提示
1<=n,m<=20000

解题思路
很久很久以前,巨龙突然出现~

用两个优先队列分别维护头的大小和每个人可以砍的头的大小,即保证花最少的钱砍最小的头。如果当前成员不能砍掉队列最前端的头(即最小的头),那说明他也不可能砍掉之后的头,(既然如此就没有存在的必要了,毁灭吧赶紧的 );而如果可以砍掉,每个人也只能砍一个头,所以不管能不能砍掉,都需要pop当前成员换下一位。当成员队列为空而头队列不为空时,说明无解,否则输出最小花费。

AC代码

#include <bits/stdc++.h>
#define MAXN 20000 + 10

using namespace std;

int read()
{
    int x = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9')
    {
        if (ch == '-')
            f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9')
    {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}

int main(int argc, char const *argv[])
{
    int n = read(), m = read(), money = 0, temp;
    priority_queue<int, vector<int>, greater<int>> heads;
    priority_queue<int, vector<int>, greater<int>> humen;
    for (int i = 0; i < n; i++)
    {
        temp = read();
        heads.push(temp);
    }
    for (int i = 0; i < m; i++)
    {
        temp = read();
        humen.push(temp);
    }
    while (!humen.empty())
    {
        if (heads.empty())
            break;
        if (humen.top() >= heads.top())
        {
            //如果当前成员能砍掉最前端的头,则加上当前成员的花费。
            money += humen.top();
            heads.pop();
        }
        humen.pop();
    }
    if (!heads.empty())
        puts("you died!");
    else
        printf("%d\n", money);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值