蓝桥杯第17169题——兽之泪II

news2024/9/23 17:24:49

问题描述

图片描述

在蓝桥王国,流传着一个古老的传说:在怪兽谷,有一笔由神圣骑士留下的宝藏。

小蓝是一位年轻而勇敢的冒险家,他决定去寻找宝藏。根据远古卷轴的提示,如果要找到宝藏,那么需要集齐 n 滴兽之泪,同时卷轴中也记载了,每击败一次怪物,就能够收集一滴兽之泪。

小蓝知道,这些怪物并非泛泛之辈,每一只都拥有强大的力量和狡猾的技巧。每一只怪物都有它独特的弱点和对策,小蓝必须谨慎选择战斗的策略和使用的能量。

在怪兽谷中,有 k 只怪兽。对于第 i 只怪兽,第一次击败他需要 xi​ 点能量,后续再击败他需要 yi​ 点能量。在挑战过程中,前 k−1 只怪兽可以随意挑战,但是第 k 只怪兽是怪兽之王,如果要挑战第 k 只怪兽,那么对于前 k−1 只怪兽都要击败至少一次

小蓝想知道,如果要集齐 n 滴兽之泪,那么至少需要多少能量。

输入格式

第一行包含一个整数 T(T≤105),代表测试组数。

每组数据包含如下部分:

第一行包含两个整数 k 和 n,表示怪物的数量和需要收集的兽之泪的数量。

2 ≤ k ≤ 10^5, 1 ≤ n ≤ 2 × 10^5。

接下来 k 行,每行包含两个整数 xi​ 和 yi​,表示第 i 只怪物第一次和后续击败所需的能量。

1 ≤ xi​, yi ​≤ 10^9。

保证 ∑k ≤ 10^5。

输出格式

对于每组数据,输出一个整数,表示小蓝至少需要多少点能量才能收集完成。

样例输入

1
3 4
2 2
4 2
1 1

样例输出

8

说明

注意,xi​,yi​ 并不保证谁大谁小。

一种可行的方案是:

  1. 第一次选择 1 号怪物,消耗能量 2。
  2. 第二次选择 2 号怪物,消耗能量 4。
  3. 由于 1,2 都已经击败一次,所以可以选择 3 号,第三次选择 3 号怪物,消耗能量 1。
  4. 第四次选择 3 号怪物,消耗能量 1。

另外一种方案是:

四次都选择 1 号怪兽,消耗的能量是 8。

解题思路

从数据量来看,解决该问题的时间复杂度不得达到O(N^2),使用二分的情况下满足时间复杂度要求,并且题目给出限制条件k的总和低于10^5,因此对每组数据进行排序是符合O(nlogn)的复杂度的,所以可以明确,此题可以使用排序、二分。

此题可以从游戏玩家的角度去思考打怪兽策略,由于一个怪兽可以多次打,那么我们肯定会想要多次去刷同一个y值消耗低的怪兽,以此刷满掉落物。

那么假设我们要一直刷的怪兽,扫荡消耗yi能量,那么首次击败所消耗的能量低于yi的怪兽就应当优先击败一次,这样可以在刷yi怪兽之前做到能量消耗最少。

我们会考虑到遍历每组数据的所有x值,其比yi小的记录到cost里,但这种方式并不会超时,但是会有另外的问题:如果比yi小的x值数量已经满足n滴眼泪的要求,我们就需要提前返回最小的n个x值总和,如果是乱序的,每次从第一个x开始遍历,那么就无法找到不考虑y只考虑x的最小能量消耗情况(也就是只挑选部分怪兽打一次就够了的情况,无法计算出最小的x总和)

所以既然排序是允许的,那么我们干脆对每组数据的x先进行排序,并使用pre数组对x做前缀和的预计算,那么在上述提到的特例情况中,就可以直接返回pre[n]的值即可。

排序之后我们会想到一个这样的做法,但它是错的:我们遍历每一个怪兽,定义其序号为j,先刷完1到j每个怪兽1次,最后不够的再刷第j个怪兽。这个方法错误的原因在于,对于一个较大的x,可能会有一个相当小的y,直白的说,帅怪的顺序可能是x1,x2,x5,y5,y5,y5……在这个可能的策略中,我们跳过了x3和x4没有刷,这种情况是有可能发生的,所以这个方法是不可行的。

最终我们的做法是,对每组数据的每个y进行枚举,考虑最后无限刷的怪兽多次击败的能量消耗是y,期间使用二分法配合前缀和计算出刷它之前需要刷的其他怪兽能量消耗,就可以找到最小的答案。

import java.util.*;
import java.io.*;

public class Main{
    public static Pair[] pairs;
    public static long[] pre;
    public static int k, n;

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int T = sc.nextInt();
        while (T-- > 0) {
            k = sc.nextInt();
            n = sc.nextInt();
            pairs = new Pair[k + 1];
            pre = new long[k + 1];
            for (int i = 1; i <= k; i++) {
                int x = sc.nextInt();
                int y = sc.nextInt();
                pairs[i] = new Pair(x, y);
            }
            // 对pairs数组的[1, k-1]进行排序,避免0下标的空指针问题
            // 第k个怪兽的x再小也不可以提前刷,必须维持在最后的位置
            Arrays.sort(pairs, 1, k, Comparator.comparing((Pair p) -> p.x));
            // 对于刷满k个怪兽的情况,后续不够的兽之泪可以刷y最小的那只怪兽
            long minY = Integer.MAX_VALUE;
            for (int i = 1; i <= k; i++) {
                pre[i] = pre[i - 1] + pairs[i].x;
                minY = Math.min(minY, pairs[i].y);
            }
            long ans = solveK(minY);
            for (int i = 1; i < k; i++) {
                ans = Math.min(ans, solve(i));
            }
            System.out.println(ans);
        }
    }

    public static long solveK(long minY) {
        long cost = pre[k];
        long tear = k;
        cost += Math.max(0, n - tear) * minY;
        return cost;
    }

    public static long solve(int yi) {
        Pair p = pairs[yi];
        // 此结构的二分下,最后的right是满足if表达式的最大下标
        int left = 1, right = k;
        while (left <= right) {
            int mid = left + (right - left) / 2;
            if (pairs[mid].x < p.y) {
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        // 如果根本不需要刷那么多,就返回pre[n]提前结束
        if (right >= n) {
            return pre[n];
        }
        long cost = pre[right];
        long tear = right;
        // 如果yi对应的x没有杀过,就单独处理一下
        if (right < yi) {
            cost += p.x;
            tear++;
        }
        cost += Math.max(0, n - tear) * p.y;
        return cost;
    }
}

class Pair {
    int x, y;

    public Pair(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1616392.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【YOLOv8改进[注意力]】YOLOv8添加DAT(Vision Transformer with Deformable Attention)助力涨点

目录 一 DAT 二 YOLOv8添加DAT助力涨点 1 总体修改 2 配置文件 3 训练 其他 一 DAT 官方论文地址&#xff1a;https://openaccess.thecvf.com/content/CVPR2022/papers/Xia_Vision_Transformer_With_Deformable_Attention_CVPR_2022_paper.pdf Transformers最近在各种视…

js连接抖音打印组件实现打印

js连接抖音打印组件实现打印小票 安装抖音打印组件 抖音打印组件文档&#xff1a; https://bytedance.larkoffice.com/docs/doccn2vbOOdd3KWrCd6Z93nIlvg 跟着文档案例一步步配基本上没问题&#xff0c; 打印的时候需要设置下打印机名称 export class DouyinPrint {construct…

完美运营版商城/拼团/团购/秒杀/积分/砍价/实物商品/虚拟商品等全功能商城

源码下载地址&#xff1a;完美运营版商城.zip 后台可以自由拖曳修改前端UI页面 还支持虚拟商品自动发货等功能 挺不错的一套源码 前端UNIAPP 后端PHP 一键部署版本

【计算机组成原理】浮点运算方法和浮点运算器

浮点加法、减法运算 浮点数加减法的步骤结合题目分析步骤 浮点数加减法的步骤 ① 0 操作数检查 ② 比较阶码大小&#xff0c;完成对阶 ③ 尾数进行加减法运算 ④ 结果规格化 ⑤ 舍入处理 ⑥ 判断结果是否溢出 结合题目分析步骤 例&#xff1a;设 x 2010 0.11011011&#x…

展商企业【广东伟创科技开发有限公司】| 2024水科技大会暨技术装备成果展

企业介绍 广东伟创科技开发有限公司成立于2006年&#xff0c;位于广东省江门市。公司是华南理工大学造纸与污染控制国家工程研究中心科技成果转化单位&#xff1b;是华南理工大学产学研合作单位&#xff1b;是广东省高新技术企业&#xff1b;是江门市现代信息服务业重点企业&am…

在线音乐播放网站项目测试(selenium+Junit5)

在做完在线音乐播放网站项目之后&#xff0c;需要对项目的功能、接口进行测试&#xff0c;利用测试的工具&#xff1a;selenium以及Java的单元测试工具Junit进行测试&#xff0c;下面式测试的思维导图&#xff0c;列出该项目需要测试的所有测试用例&#xff1a; 测试结果&#…

嵌入式系统相关知识总结

一、概述 嵌入式系统是以应用为中心、以计算机技术为基础&#xff0c;并将可配置与可裁剪的软、硬件集成与一体的专用计算机系统&#xff0c;需要满足应用对功能、可靠性、成本、提及和功耗等方面的严格要求。 从计算机角度看&#xff0c;嵌入式系统是指嵌入各种设备及应用产品…

使用Jest测试框架测试JS项目

前言 JavaScript的测试框架有很多&#xff0c;这里主要记录一些自己在初次使用jest时遇到的一些问题。详细使用文档可以参照官方说明文档。 简介 Jest 是一款优雅、简洁的 JavaScript 测试框架。 Jest 支持 Babel、TypeScript、Node、React、Angular、Vue 等诸多框架&#…

软件测试之【合理的利用GPT来辅助软件测试一】

读者大大们好呀&#xff01;&#xff01;!☀️☀️☀️ &#x1f525; 欢迎来到我的博客 &#x1f440;期待大大的关注哦❗️❗️❗️ &#x1f680;欢迎收看我的主页文章➡️寻至善的主页 文章目录 前言GPT的原理及技巧GPT辅助接口自动化测试 前言 在编程基础栏目中&#xff…

循环神经网络实例——序列预测

我们生活的世界充满了形形色色的序列数据&#xff0c;只要是有顺序的数据统统都可以看作是序列数据&#xff0c;比如文字是字符的序列&#xff0c;音乐是音符组成的序列&#xff0c;股价数据也是序列&#xff0c;连DNA序列也属于序列数据。循环神经网络RNN天生就具有处理序列数…

嵌入式linux学习之arm开发板移植ssh

1.下载源码 &#xff08;1&#xff09;zlib 下载网址&#xff1a;http://www.zlib.net/fossils/ 教程中版本选择的是: zlib-1.2.11.tar.gz &#xff08;2&#xff09;openssl下载网址&#xff1a;https://www.openssl.org/source/mirror.html 教程中版本选择的是: openssl-1.1…

用友U8-Cloud api/hr接口存在SQL注入漏洞

声明&#xff1a; 本文仅用于技术交流&#xff0c;请勿用于非法用途 由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;文章作者不为此承担任何责任。 简介 U8 Cloud是由用友推出的新一代云ERP系统&#xff0…

VSCode的C/C++开发 ===> Windows

一、开发环境搭建 安装mingw-w64编译器(GCC for Windows 64 & 32 bits)、Cmake工具(选装) VSCode插件安装 C/C cmake cmake tools 二、代码实践演练 基于g命令 g编译单文件&#xff0c;生成带调试信息的可执行文件、并调试 g -g main.cpp -o my_single_swap g编译多文件…

【C#】rdlc报表答应报错:未能加载文件或程序集“Microsoft.SqlServer.Types

文章目录 一、报错信息二、解决方式 一、报错信息 Microsoft.Reporting.WinForms.LocalProcessingException: An error occurred during local report processing. —> Microsoft.Reporting.DefinitionInvalidException: The definition of the report ‘’ is invalid. —&…

算法练习|Leetcode49字母异位词分词 ,Leetcode128最长连续序列,Leetcode3无重复字符的最长子串,sql总结

目录 一、Leetcode49字母异位词分词题目描述解题思路方法:哈希总结 二、Leetcode128最长连续序列题目描述解题思路方法:总结 三、Leetcode3无重复字符的最长子串题目描述解题思路方法:双指针法总结sql总结 一、Leetcode49字母异位词分词 题目描述 给你一个字符串数组&#xf…

数据结构与算法解题-20240422

这里写目录标题 一、2. 两数相加二、67. 二进制求和三、415. 字符串相加四、LCS 01. 下载插件五、71. 简化路径 一、2. 两数相加 给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 …

分享三个转换速度快、准确率高的视频转文字工具

想要直接将视频转换成文字&#xff0c;转换工具很重要&#xff01;给大家分享三个转换速度快、准确率高的视频转文字工具&#xff0c;轻松完成转换。 1.网易见外 https://sight.youdao.com/ 网易家的智能转写翻译服务工作站&#xff0c;网页端就可以直接使用&#xff0c;支持视…

vi, vim,data,wc,系统常用命令-读书笔记(十)

vi 文本编辑器 基本上 vi 共分为三种模式&#xff0c;分别是“一般指令模式”、“编辑模式”与“命令行命令模式”。这三种模式的作用分别是&#xff1a; 一般指令模式&#xff08;command mode&#xff09;以 vi 打开一个文件就直接进入一般指令模式了&#xff08;这是默认的…

Elasticsearch:崭新的打分机制 - Learning To Rank (LTR)

警告&#xff1a;“学习排名 (Learning To Rank)” 功能处于技术预览版&#xff0c;可能会在未来版本中更改或删除。 Elastic 将努力解决任何问题&#xff0c;但此功能不受官方 GA 功能的支持 SLA 的约束。 注意&#xff1a;此功能是在版本 8.12.0 中引入的&#xff0c;并且仅适…

GEE:基于光谱距离度量方法的巴以冲突造成的地表覆盖变化检测

作者:CSDN @ _养乐多_ 本文将介绍如何在 Google Earth Engine (GEE) 平台中使用光谱距离度量方法进行地表覆盖变化检测,并以加沙地区为例,使用Sentinel2数据展示2023年3月和2024年3月的地表覆盖变化区域。 结果如下图所示, 文章目录 一、核心函数1.1 spectralDistance函数…