序列
序列
给定 个序列,每个包含 个非负整数。
现在我们可以从每个序列中选择一个数字以形成具有 个整数的序列。
很明显,我们一共可以得到 个这种序列,然后我们可以计算每个序列中的数字之和,并得到 个值。
现在请你求出这些序列和之中最小的 个值。
输入格式
第一行输入一个整数 ,代表输入中包含测试用例的数量。
接下来输入 组测试用例。
对于每组测试用例,第一行输入两个整数 和 。
接下在 行输入 个整数序列,数列中的整数均不超过 。
输出格式
对于每组测试用例,均以递增顺序输出最小的 个序列和,数值之间用空格隔开。
每组输出占一行。
数据范围
,
输入样例:
1 2 3 1 2 3 2 2 3
输出样例:
3 3 4
解题思路
题目就是给定个序列,每个序列的长度都是,然后从每个序列中选出一个数组成一个新序列,求各个新序列的和并输出前个最小的和。
可以把这个过程看作是把个序列合并成一个长度为的序列。如果直接合并个序列并不好做,因此我们可以每次合并两个序列,合并次后这个序列就被合并了。比如第一次先合并第个和第个序列,合并就是在这两个序列中每个序列都选出一个数,然后求和,一共会得到个和。因为求的是前个最小的和,因此只保留前个和。然后用这个长度为的新序列继续与原本第个序列进行合并的操作,以此类推,一共进行次。
如果只有两个序列,当进行合并的时候,如果直接暴力来把个数全部求出来,再排序选出前个数,那么每一次合并的时间复杂度都是,那么整个算法的时间复杂度就是,一定会超时的。
做法是分组,考虑要合并两个序列和,先将序列排好序,因为有个和,把这些和分成组。
因为序列是从小到大排好序的,每一组都加上同一个数,因此每一组都是从小到大排好序的,所以每一组中的第一个数是当前组中最小的那一个数,因此这个数中最小的数就在每一组的第一个数中(也就是从每一组的最小数中选一个最小的数)。把每一组的第一个数选出来放到一个集合中,假设一开始这个数中最小的是,那么我们就把从这些数中删掉,把加进来(这个数在组中的下一个数),那么第小数仍然是从这个数的集合中选最小的数(从每一组的最小数中选一个最小的数,而当前第组中最小的数是)。以此类推,一共选出个数为止。可以发现维护这个集合的操作可以用堆来实现。
这个过程可以看作是路归并,只不过是用堆来实现。
AC代码如下,时间复杂度为:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 typedef pair<int, int> PII; 5 6 const int N = 2010; 7 8 int n, m; 9 int a[N], b[N], c[N]; 10 11 void merge() { 12 priority_queue<PII, vector<PII>, greater<PII>> pq; 13 for (int i = 0; i < n; i++) { 14 pq.push({a[0] + b[i], 0}); // 把每一组的最小的数放入堆中 15 } 16 17 for (int i = 0; i < n; i++) { 18 PII t = pq.top(); 19 pq.pop(); 20 21 c[i] = t.first; // 从每组的最小数中选最小的数 22 pq.push({t.first - a[t.second] + a[t.second + 1], t.second + 1}); // 放入这个数所在组的下一个数 23 } 24 25 memcpy(a, c, sizeof(c)); 26 } 27 28 int main() { 29 int tot; 30 scanf("%d", &tot); 31 while (tot--) { 32 scanf("%d %d", &m, &n); 33 for (int i = 0; i < n; i++) { 34 scanf("%d", a + i); 35 } 36 37 sort(a, a + n); // 先对第1组排序,后面的组不需要排序 38 39 for (int i = 0; i < m - 1; i++) { 40 for (int j = 0; j < n; j++) { 41 scanf("%d", b + j); 42 } 43 merge(); // 对序列a和b进行合并,并把结果存到a中 44 } 45 46 for (int i = 0; i < n; i++) { 47 printf("%d ", a[i]); 48 } 49 printf("\n"); 50 } 51 52 return 0; 53 }
参考资料
AcWing 146. 序列:https://www.acwing.com/video/125/
本文来自博客园,作者:onlyblues,转载请注明原文链接:https://www.cnblogs.com/onlyblues/p/16617986.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效