算法刷题day25:多路归并

news2024/11/18 8:12:55

目录

  • 引言
  • 概念
  • 一、鱼塘钓鱼
  • 二、技能升级
  • 三、序列

引言

关于这个多路并归蓝桥杯考的不是很多,如果要出的话,可能模型都会差不多,因为不会出太难的题,难题基本上都是贪心、DP之类的,所以好好刷题刷熟练就行了,见过熟悉即可,加油!


概念

多路归并:首先可以参考博客算法刷题:归并排序、归并排序,这个多路归并其实就是一种类型的题目,还是要因题而异。


一、鱼塘钓鱼

标签:多路归并

思路: 1. 1. 1. 首先核心就是则个人钓鱼不会折返跑,因为每个鱼塘钓的鱼的数量是和你钓的次数有关,和时间无关,如果你又折返跑回来钓的话,还不如就直接在上一次的鱼塘多钓几次,还浪费路上的时间,所以最优解肯定是一条直线,而不会是来回的跑,因为这个 N N N 比较小,所以我们可以直接枚举最远的池塘数来计算最大值。 2. 2. 2. 我们可以提前把路程减去,然后只剩下钓鱼的时间了,所以就相当于在这多个鱼塘里钓,由于钓一次都是一分钟,并且没有路程的计算,所以就挑最大的几个就行了,也就是多个数 a [ i ] a[i] a[i] ,每个数取了就递减 d [ i ] d[i] d[i] 个,求最多能取多少个数,直接拿堆来模拟即可。

题目描述:

有 N 个鱼塘排成一排,每个鱼塘中有一定数量的鱼,例如:N=5 时,如下表:

鱼塘编号	                                       1	2	3	4	5
第1分钟能钓到的鱼的数量(1..1000)	              10	14	20	16	9
每钓鱼1分钟钓鱼数的减少量(1..100)	               2	4	6	5	3
当前鱼塘到下一个相邻鱼塘需要的时间(单位:分钟)	3	5	4	4	
即:在第 1 个鱼塘中钓鱼第 1 分钟内可钓到 10 条鱼,第 2 分钟内只能钓到 8 条鱼,……,第 5 分钟以后再也钓不到鱼了。

从第 1 个鱼塘到第 2 个鱼塘需要 3 分钟,从第 2 个鱼塘到第 3 个鱼塘需要 5 分钟,……

给出一个截止时间 T,设计一个钓鱼方案,从第 1 个鱼塘出发,希望能钓到最多的鱼。

假设能钓到鱼的数量仅和已钓鱼的次数有关,且每次钓鱼的时间都是整数分钟。

输入格式
共 5 行,分别表示:
第 1 行为 N;
第 2 行为第 1 分钟各个鱼塘能钓到的鱼的数量,每个数据之间用一空格隔开;
第 3 行为每过 1 分钟各个鱼塘钓鱼数的减少量,每个数据之间用一空格隔开;
第 4 行为当前鱼塘到下一个相邻鱼塘需要的时间;
第 5 行为截止时间 T。

输出格式
一个整数(不超过231−1),表示你的方案能钓到的最多的鱼。

数据范围
1≤N≤100 ,1≤T≤1000
输入样例:
5
10 14 20 16 9
2 4 6 5 3
3 5 4 4
14
输出样例:
76

示例代码:

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
typedef pair<int,int> PII;

const int N = 110;

int n, T;
int a[N], d[N], l[N];

LL work(int x, int t)
{
    if(t <= 0) return 0;
    priority_queue<PII> heap;
    for(int i = 1; i <= x; ++i) heap.push({a[i], i});
    
    LL res = 0;
    while(t-- && heap.size())
    {
        auto t1 = heap.top(); heap.pop();
        int v = t1.first, p = t1.second;
        res += v;
        if(v - d[p] > 0) heap.push({v-d[p], p});
    }
    
    return res;
}

int main()
{
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    
    cin >> n;
    for(int i = 1; i <= n; ++i) cin >> a[i];
    for(int i = 1; i <= n; ++i) cin >> d[i];
    for(int i = 2; i <= n; ++i) 
    {
        cin >> l[i];
        l[i] += l[i-1];
    }
    
    cin >> T;
    LL res = 0;
    for(int i = 1; i <= n; ++i)
    {
        res = max(res, work(i, T - l[i]));
    }
    
    cout << res << endl;
}

二、技能升级

标签:多路归并

思路:明显可以看出这道题是上一道题的简化版,也就是这道题是包含在上道题里的,也就是 w o r k work work 函数,但由于这道题的 M M M 的值比较大,所以如果用 h e a p heap heap 来做的话,能过 7 12 \frac{7}{12} 127 个数据,所以要另辟蹊径了。我们假设所有的可能的数第 M M M 个数值为 mid ,那么最大值就是取前 M M M 个数了,所以我们只要 mid 确定了下来,剩余就可以遍历每个序列用数学公式就能计算出来总和。然后我们能够知道小于等于 mid 的个数一定是大于等于 M 的,所以具有二段性可以用二分来写,具体细节见代码。

题目描述:

小蓝最近正在玩一款 RPG 游戏。

他的角色一共有 N 个可以加攻击力的技能。

其中第 i 个技能首次升级可以提升 Ai 点攻击力,以后每次升级增加的点数都会减少 Bi。

⌈AiBi⌉(上取整)次之后,再升级该技能将不会改变攻击力。现在小蓝可以总计升级 M 次技能,他可以任意选择升级的技能和次数。

请你计算小蓝最多可以提高多少点攻击力?

输入格式
输入第一行包含两个整数 N 和 M。
以下 N 行每行包含两个整数 Ai 和 Bi。

输出格式
输出一行包含一个整数表示答案。

数据范围
对于 40% 的评测用例,1≤N,M≤1000;
对于 60% 的评测用例,1≤N≤104,1≤M≤107;
对于所有评测用例,1≤N≤105,1≤M≤2×109,1≤Ai,Bi≤106。

输入样例:
3 6
10 5
9 2
8 1
输出样例:
47

示例代码:

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

const int N = 1e5+10;

int n, m;
int a[N], b[N];

bool check(int mid)
{
    LL sum = 0;
    for(int i = 1; i <= n; ++i)
    {
        if(a[i] >= mid)
        {
            sum += (a[i] - mid) / b[i] + 1;
        }
    }
    return sum >= m;
}

int main()
{
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    
    cin >> n >> m;
    for(int i = 1; i <= n; ++i) cin >> a[i] >> b[i];
    
    int l = 0, r = 1e6;
    while(l < r)
    {
        int mid = (LL)l + r + 1 >> 1;
        if(check(mid)) l = mid;
        else r = mid - 1;
    }
    
    LL res = 0, cnt = 0;
    for(int i = 1; i <= n; ++i)
    {
        if(a[i] >= r)
        {
            int c = (a[i] - r) / b[i] + 1;
            int end = a[i] - (c - 1) * b[i];
            cnt += c;
            res += (LL)(a[i] + end) * c / 2;
        }
    }
    
    cout << res - (cnt - m) * r << endl;  // 可能会有多个r,数量超过了m
    return 0;
}

三、序列

标签:多路归并

思路:这是一个典型的从 m m m n n n 列中,每一行选一个数组,求选到的数字之和最小的 n n n 个。我们可以先两行两行的合并找到最小的 n n n 个,然后遍历 m − 1 m - 1 m1 次,这样最后的 n n n 个数字就是最小的了。然后两个合并,我们可以先把 a a a 数组排个序,然后把这 n 2 n ^ 2 n2 的数排成 n n n 组,如下图所示,由于 a a a 是排好序了,所以每组最小的就是最前边的那个,然后把这 n n n 个数加入到堆中,然后记下当前下标,然后再变成每组下一个数即可,这样下来的 n n n 个数就是最小的了。
在这里插入图片描述

题目描述:

给定 m 个序列,每个包含 n 个非负整数。

现在我们可以从每个序列中选择一个数字以形成具有 m 个整数的序列。

很明显,我们一共可以得到 nm 个这种序列,然后我们可以计算每个序列中的数字之和,并得到 nm 个值。

现在请你求出这些序列和之中最小的 n 个值。

输入格式
第一行输入一个整数 T,代表输入中包含测试用例的数量。

接下来输入 T 组测试用例。

对于每组测试用例,第一行输入两个整数 m 和 n。

接下在 m 行输入 m 个整数序列,数列中的整数均不超过 10000。

输出格式
对于每组测试用例,均以递增顺序输出最小的 n 个序列和,数值之间用空格隔开。

每组输出占一行。

数据范围
0<m≤1000,0<n≤2000
输入样例:
1
2 3
1 2 3
2 2 3
输出样例:
3 3 4

示例代码:

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
typedef pair<int,int> PII;

const int N = 2010;

int T;
int m, n;
int a[N], b[N], c[N];

void merge()
{
    priority_queue<PII, vector<PII>, greater<PII>> heap;
    for(int i = 0; i < n; ++i) heap.push({a[0] + b[i], 0});
    
    for(int i = 0; i < n; ++i)
    {
        auto t = heap.top(); heap.pop();
        int v = t.first, p = t.second;
        c[i] = v;
        heap.push({v - a[p] + a[p+1], p+1});
    }
    
    memcpy(a, c, sizeof a);
}

int main()
{
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    
    cin >> T;
    while(T--)
    {
        cin >> m >> n;
        for(int i = 0; i < n; ++i) cin >> a[i];
        
        sort(a, a+n);
        for(int i = 0; i < m - 1; ++i)
        {
            for(int j = 0; j < n; ++j) cin >> b[j];
            merge();
        }
        
        for(int i = 0; i < n; ++i) cout << a[i] << " ";
        cout << endl;
    }
    
    return 0;
}

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

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

相关文章

探讨2024年AI辅助研发的趋势

一、引言 随着科技的飞速发展&#xff0c;人工智能&#xff08;AI&#xff09;已经成为当今时代最具变革性的技术之一。AI的广泛应用正在重塑各行各业&#xff0c;其中&#xff0c;AI辅助研发作为科技和工业领域的一大创新热点&#xff0c;正引领着研发模式的深刻变革。从医药…

安卓7原生相机切到视频崩溃

目录 1、查看日志 2、分析日志、提取重点 3、寻找解决方法 author daisy.skye的博客_CSDN博客-嵌入式,Qt,Linux领域博主 daisy.skye_嵌入式,Linux,Qt-CSDN博客daisy.skye擅长嵌入式,Linux,Qt,等方面的知识https://blog.csdn.net/qq_40715266?typeblog 1、查看日志 由于安…

帮管客 CRM jiliyu SQL注入漏洞复现

0x01 产品简介 帮管客CRM是一款集客户档案、销售记录、业务往来等功能于一体的客户管理系统。帮管客CRM客户管理系统,客户管理,从未如此简单,一个平台满足企业全方位的销售跟进、智能化服务管理、高效的沟通协同、图表化数据分析帮管客颠覆传统,重新定义企业管理系统。 …

Redis核心数据结构之字典(二)

字典 解决键冲突 当有两个或以上数量的键被分配到了一个哈希表数组的同一个索引上面&#xff0c;我们称这些键发生了冲突(collision)。 Redis的哈希表使用链地址法(separate chaining)来解决键冲突&#xff0c;每个哈希表节点都有一个next指针&#xff0c;多个哈希表节点可以…

python三剑客之一——Numpy

温故而知新&#xff0c;借着工作需要用到Numpy的机会重新学习一遍Numpy。 Numpy是一个运行速度非常快的数学库&#xff0c;主要用于数组计算&#xff0c;包含如下&#xff1a; 一个强大的N维数组对象ndarray【Nd&#xff08;Dimension维度&#xff09;array】 广播功能函数 整…

九型人格测试,9号和平型人格的职业分析业?

九型人格测试&#xff0c;人格分为9个类型&#xff0c;而和平型人格&#xff0c;也就是我们所说的和平使者&#xff0c;为人非常善良&#xff0c;十分地体贴&#xff0c;能够体谅到对方的难处&#xff0c;并且会大度地原谅对方的错误。愿意去了解对方&#xff0c;但却没有时间在…

支小蜜校园防欺凌系统听到声音之后会自动识别吗

在校园安全领域&#xff0c;特别是在预防和应对欺凌问题上&#xff0c;校园防欺凌系统作为新兴的技术应用&#xff0c;正在受到越来越多的关注和探索。那么当这样的系统听到声音之后&#xff0c;它是否能够自动识别并作出相应反应呢&#xff1f;本文将围绕这一问题展开探讨。 …

JAVA虚拟机实战篇之内存调优[4](内存溢出问题案例)

文章目录 版权声明修复问题内存溢出问题分类 分页查询文章接口的内存溢出问题背景解决思路问题根源解决思路 Mybatis导致的内存溢出问题背景问题根源解决思路 导出大文件内存溢出问题背景问题根源解决思路 ThreadLocal占用大量内存问题背景问题根源解决思路 文章内容审核接口的…

编译内核错误 multiple definition of `yylloc‘

编译内核错误 # make ARCHarm CROSS_COMPILEarm-mix410-linux- uImageHOSTLD scripts/dtc/dtc /usr/bin/ld: scripts/dtc/dtc-parser.tab.o:(.bss0x10): multiple definition of yylloc; scripts/dtc/dtc-lexer.lex.o:(.bss0x0): first defined here collect2: error: ld ret…

c++提高部分

c++提高部分 这部分主要涉及泛型编程和STL技术 1. 模版 1.1 模版的概念 模版就是通用的模具,大大提高复用性,但需要根据需求改动一些东西 1.2 函数模版 c++另一种编程思想为泛型编程,主要利用的技术就是模版c++提供两种模版机制:函数模板和类模板1.2.1 函数模板语法 …

C++ 篇 数组

数组是含有多个数据项的数据结构&#xff0c;并且这些数据项都具有相同的数据类型。这些数据项称为数组的元素&#xff0c;我们可以根据元素在数组中的位置来选取元素。 最简单的数组就是一维数组。数组元素在内存中是依次排列的&#xff0c;如下图所示&#xff1a; 声明一个…

js【详解】原型 vs 原型链

原型 每个 class 都有显示原型 prototype每个实例都有隐式原型_proto_实例的_proto_指向对应 class 的 prototype 如下范例&#xff1a; class Student 创建了 实例 xialuo 获取属性 xialuo.name 或执行方法 xialuo.sayhi()时&#xff0c;先在自身属性和方法寻找&#xff0…

1.5如何缓解图像分类任务中训练数据不足带来的问题?

1.5 图像数据不足时的处理方法 场景描述 在机器学习中&#xff0c;绝大部分模型都需要大量的数据进行训练和学习(包括有监督学习和无监督学习)&#xff0c;然而在实际应用中经常会遇到训练数据不足的问题。 比如图像分类&#xff0c;作为计算机视觉最基本的任务之一&#xff0…

C++进阶之路---继承(二)

顾得泉&#xff1a;个人主页 个人专栏&#xff1a;《Linux操作系统》 《C从入门到精通》 《LeedCode刷题》 键盘敲烂&#xff0c;年薪百万&#xff01; 一、继承与友元 友元关系不能继承&#xff0c;也就是说基类友元不能访问子类私有和保护成员。 class Student; class Per…

机器学习——神经网络压缩

神经网络压缩 需要部署&#xff0c;设备内存和计算能力有限&#xff0c;需要进行模型压缩&#xff0c;在设备上运行的好处是低延迟&#xff0c;隐私性。 目录 不考虑硬件问题&#xff0c;只考虑通过软件算法优化。 修剪网络 参数过多或者没有用的参数&#xff0c;可以将其剪…

JavaWeb笔记 --- 二、Maven

二、Maven Maven概述 所有的IDE创建的Maven项目都可以使用 Maven简介 Maven模型 Maven常用命令 Maven生命周期 Maven坐标 依赖管理 dpendencies&#xff1a;依赖 依赖范围

Matlab|基于目标级联法的微网群多主体分布式优化调度

目录 主要内容 1.1 上层微网群模型 1.2 下层微网模型 部分程序 实现效果 下载链接 主要内容 本文复现《基于目标级联法的微网群多主体分布式优化调度》文献的目标级联部分&#xff0c; 建立微网群系统的两级递阶优化调度模型: 上层是微网群能量调度中心优化调度…

考研数学|张宇30讲,搭配什么基础题?

如果基础跟的是张宇&#xff0c;那么基础做的题目要根据自己的题目来决定 题集的选择最好不要太难&#xff0c;而且基础也不用做太多题目&#xff0c;以数学知识点的运用&#xff0c;培养做题感觉为主。 张宇老师的课程在基础阶段也有配套的课程&#xff0c;就是《张宇基础30…

二维码门楼牌管理系统应用场景:推动旅游与文化产业的智慧化升级

文章目录 前言一、二维码门楼牌管理系统在旅游领域的应用二、二维码门楼牌管理系统在文化产业的应用三、结语 前言 随着信息技术的不断发展&#xff0c;二维码门楼牌管理系统作为一种创新的信息化手段&#xff0c;正在逐渐渗透到旅游和文化领域。它通过为文化景点、旅游景点和…

【动态规划.3】[IOI1994]数字三角形 Number Triangles

题目 https://www.luogu.com.cn/problem/P1216 观察下面的数字金字塔。 写一个程序来查找从最高点到底部任意处结束的路径&#xff0c;使路径经过数字的和最大。每一步可以走到左下方的点也可以到达右下方的点。 7→3→8→7→5 的路径产生了最大权值。 分析 这是一个动态规划…