UVA11997求前k个和,多路归并问题
题意:
给你一个二维矩阵,n*n的,每次从每一行中拿出来一个,然后加起来组成一个和,一共可以得到n^n个和,要求求出这n^n个和中最小的那n个和。
思路:
多路归并问题,先说下多路归并问题,我的理解是有个变量,每个变量都按照自己的变化规律在变化着,每次一旦选用每个变量,那么这个变量就会根据自己的变化规律变化,这种问题我们可以用优先队列来解决,首先我们可以把所有变量都扔进队列,然后在在里面取出一个最小的(或者最大的)作为当前答案,然后把取出来的数值变化后在扔进队列里,如此反复操作,对于这个题目我们可以像白书上一样这样分析,首先我们想一个该问题的简化版,就是给你两个数组,每个数组里面有n个数字,每次从两个数组中任意取出一个数字加起来得到一个和,求前n个最小的和。
我们可以运用多路归并问题
A[1]+B[1] <= A[1]+B[2] <= A[1]+B[3]...
A[2]+B[1] <= A[2]+B[2] <= A[2]+B[3]...
A[3]+B[1] <= A[3]+B[2] <= A[3]+B[3]...
...
对于每一个集合的每一个变量我们可以这样表示,node.s = A[a] + A[b] ,node.b =b;
这样这个集合的下一个变量就是 node.s - B[node.b] + B[node.b + 1] ,node.b ++;
这样说应该没问题吧? 然后我们就开始多路归并,很容易理解和想到,我们直接先把第一列圈放进队列,然后取出一个最为最小的那个,然后把取出的这个的右侧(下一个)放进队列,然后在取,在放,每次都把取出的下一个放进去,执行n此之后就得到了这最小的n个数,这是两个序列的,这个题目是n个序列,这样我们可以吧第一个和第二个合并,然后在用合并的序列去合并第三个,最后把所有的序列都合并,这里说的合并就是前面上多那个多路归并。
#include<queue>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define N 750 + 5
using namespace std;
typedef struct NODE
{
int s ,b;
friend bool operator < (NODE a ,NODE b)
{
return a.s > b.s;
}
}NODE;
int num[N][N];
int A[N] ,B[N] ,C[N];
NODE xin ,tou;
void duoluguibing(int n)
{
priority_queue<NODE>q;
for(int i = 1 ;i <= n ;i ++)
{
xin.b = 1;
xin.s = A[i] + B[1];
q.push(xin);
}
for(int i = 1 ;i <= n ;i ++)
{
tou = q.top();
q.pop();
C[i] = tou.s;
xin.b = tou.b + 1;
xin.s = tou.s - B[tou.b] + B[xin.b];
if(xin.b <= n) q.push(xin);
}
return;
}
int main ()
{
int n ,i ,j;
while(~scanf("%d" ,&n))
{
for(i = 1 ;i <= n ;i ++)
{
for(j = 1 ;j <= n ;j ++)
scanf("%d" ,&num[i][j]);
sort(num[i] + 1 ,num[i] + n + 1);
}
for(i = 1 ;i <= n ;i ++)
C[i] = num[1][i];
for(i = 2 ;i <= n ;i ++)
{
for(j = 1 ;j <= n ;j ++)
A[j] = C[j] ,B[j] = num[i][j];
duoluguibing(n);
}
for(i = 1 ;i <= n ;i ++)
if(i == n) printf("%d\n" ,C[i]);
else printf("%d " ,C[i]);
}
return 0;
}
UVA11997求前k个和,多路归并问题的更多相关文章
- 两个序列求前k大和
---恢复内容开始--- 没有题目,没有题意,这是学长提过的一个技巧,给你两个排好序的序列,每次可以各从中取一个,求前k大的和, 一个优先队列,先将a序列中最大的那个和b序列所有元素相加存进队列中,每 ...
- BZOJ2006:超级钢琴(ST表+堆求前K大区间和)
Description 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐. 这架超级钢琴可以弹奏出n个音符,编号为1至n.第i个音符的美妙度 ...
- 算法导论学习之线性时间求第k小元素+堆思想求前k大元素
对于曾经,假设要我求第k小元素.或者是求前k大元素,我可能会将元素先排序,然后就直接求出来了,可是如今有了更好的思路. 一.线性时间内求第k小元素 这个算法又是一个基于分治思想的算法. 其详细的分治思 ...
- 牛客第六场 J.Heritage of skywalkert(On求前k大)
题目传送门:https://www.nowcoder.com/acm/contest/144/J 题意:给一个function,构造n个数,求出其中任意两个的lcm的最大值. 分析:要求最大的lcm, ...
- HDU 6041 I Curse Myself(点双联通加集合合并求前K大) 2017多校第一场
题意: 给出一个仙人掌图,然后求他的前K小生成树. 思路: 先给出官方题解 由于图是一个仙人掌,所以显然对于图上的每一个环都需要从环上取出一条边删掉.所以问题就变为有 M 个集合,每个集合里面都有一堆 ...
- 隐式Dijkstra:在状态集合中用优先队列求前k小
这种技巧是挺久以前接触的了,最近又突然遇到几道新题,于是总结了一下体会. 这种算法适用的前提是,标题所述的"状态集合"大到不可枚举(否则枚举就行了qaq) ...
- D - K Smallest Sums(多路归并+贪心)
Problem K K Smallest Sums You're given k arrays, each array has k integers. There are kk ways to pic ...
- HDU - 6041:I Curse Myself(Tarjan求环&K路归并)
There is a connected undirected graph with weights on its edges. It is guaranteed that each edge app ...
- [csu/coj 1080]划分树求区间前k大数和
题意:从某个区间内最多选择k个数,使得和最大 思路:首先题目给定的数有负数,如果区间前k大出现负数,那么负数不选和更大,于是对于所有最优选择,负数不会出现,所以用0取代负数,问题便转化为区间的前k大数 ...
随机推荐
- python带颜色打印字符串
python带颜色打印字符串 之前调试pwn题的时候,有时候需要将某些特别的,重要的信息用不一样的颜色打印出来.查阅一些资料,了解了print函数的特性后,自己写了一个脚本,可以用来获取带颜色信息的字 ...
- linux 设置DNS解决,不能ping 域名的问题
vi /etc/resolv.conf nameserver 114.114.114.114
- 谈谈注册中心 zookeeper 和 eureka中的CP和 AP
谈谈注册中心 zookeeper 和 eureka中的CP和 AP 前言 在分布式架构中往往伴随CAP的理论.因为分布式的架构,不再使用传统的单机架构,多机为了提供可靠服务所以需要冗余数据因而会存在分 ...
- WPF 基础 - Window 启动动画
<Window ... WindowStyle="None" AllowsTransparency="True" RenderTransformOrigi ...
- 04-Spring自定义标签解析
自定义标签的解析 这一篇主要说明自定义标签的解析流程,除了 bean.alias.import.beans之外的标签,都属于自定义标签的范围,自定义标签的解析需要命名空间配合, 获取对应的命名空间 根 ...
- ICPC题目选讲
Traveling in the grid world 题目描述 有一个 \(n\times m\) 的格点图,两点之间走他们的连线,但是这条连线不能恰好覆盖其他整点.还要求相邻两步之间的连线不能斜率 ...
- [HDU5592] ZYB's Premutation
[HDU5592] ZYB's Premutation 题目大意:一个由\([1,n]\)组成的数列,但不知道具体排列,但给出每个前缀的逆序对数目,让你还原排列 Solution 创造一颗\([1,n ...
- Dart 学习
语言特性 Dart所有的东西都是对象, 即使是数字numbers.函数function.null也都是对象,所有的对象都继承自Object类. Dart动态类型语言, 尽量给变量定义一个类型,会更安全 ...
- Java8 Stream 中 List 转 Map 问题总结
在使用 Java 的新特性 Collectors.toMap() 将 List 转换为 Map 时存在一些不容易发现的问题,这里总结一下备查. 空指针风险 java.lang.NullPointerE ...
- Net Core 重要的技术点
Net Core 重要的技术点 1.中间件概念 Asp.Net Core作为控制台应用程序启动,在Program的Main方法是入口,通过调用CreateWebHostBuilder创建WebHost ...