题意:

     给你一个二维矩阵,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个和,多路归并问题的更多相关文章

  1. 两个序列求前k大和

    ---恢复内容开始--- 没有题目,没有题意,这是学长提过的一个技巧,给你两个排好序的序列,每次可以各从中取一个,求前k大的和, 一个优先队列,先将a序列中最大的那个和b序列所有元素相加存进队列中,每 ...

  2. BZOJ2006:超级钢琴(ST表+堆求前K大区间和)

    Description 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐. 这架超级钢琴可以弹奏出n个音符,编号为1至n.第i个音符的美妙度 ...

  3. 算法导论学习之线性时间求第k小元素+堆思想求前k大元素

    对于曾经,假设要我求第k小元素.或者是求前k大元素,我可能会将元素先排序,然后就直接求出来了,可是如今有了更好的思路. 一.线性时间内求第k小元素 这个算法又是一个基于分治思想的算法. 其详细的分治思 ...

  4. 牛客第六场 J.Heritage of skywalkert(On求前k大)

    题目传送门:https://www.nowcoder.com/acm/contest/144/J 题意:给一个function,构造n个数,求出其中任意两个的lcm的最大值. 分析:要求最大的lcm, ...

  5. HDU 6041 I Curse Myself(点双联通加集合合并求前K大) 2017多校第一场

    题意: 给出一个仙人掌图,然后求他的前K小生成树. 思路: 先给出官方题解 由于图是一个仙人掌,所以显然对于图上的每一个环都需要从环上取出一条边删掉.所以问题就变为有 M 个集合,每个集合里面都有一堆 ...

  6. 隐式Dijkstra:在状态集合中用优先队列求前k小

    这种技巧是挺久以前接触的了,最近又突然遇到几道新题,于是总结了一下体会. 这种算法适用的前提是,标题所述的"状态集合"大到不可枚举(否则枚举就行了qaq) ...

  7. 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 ...

  8. 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 ...

  9. [csu/coj 1080]划分树求区间前k大数和

    题意:从某个区间内最多选择k个数,使得和最大 思路:首先题目给定的数有负数,如果区间前k大出现负数,那么负数不选和更大,于是对于所有最优选择,负数不会出现,所以用0取代负数,问题便转化为区间的前k大数 ...

随机推荐

  1. `vi`——终端中的编辑器

    `vi`--终端中的编辑器 目标* `vi` 简介* 打开和新建文件* 三种工作模式* 常用命令* 分屏命令* 常用命令速查图 01. `vi` 简介 1.1 学习 `vi` 的目的 * 在工作中,要 ...

  2. Asp.Net Core WebAPI中启用XML格式数据支持

    因为XML是一种非常常用的数据格式,所以Asp.Net core提供了非常便利的方式来添加对XML格式的支持 只需要在IOC注册Controller服务的后面跟上.AddXmlDataContract ...

  3. 安全框架Drozer安装和简单使用

    安全框架Drozer安装和简单使用 说明: drozer(即以前的Mercury)是一个开源的Android安全测试框架 drozer不是什么新工具,但确实很实用,网上的资料教程都很多了,最近自己项目 ...

  4. python爬虫加定时任务,制作微信提醒备忘录

    一.任务的记录与提取 1.1 制作每日任务 为了便于爬取,推荐使用网页版的在线记事本,现在这种工具很多,我选择"石墨文档"进行操作演示.记录内容的 格式可以根据自己的需求和爬虫自行 ...

  5. MongoDB4.2 分片扫盲说明

    说明: 在扫盲MongoDB相关的一些知识的时候,顺手做下笔记.本文将说明分片相关的内容.在比较早之前已经对这些有过说明,可以看MongoDB 分片的原理.搭建.应用.分片(sharding)是指将数 ...

  6. Hdu 4821 (字符串hash+map)

    题目链接https://vjudge.net/problem/HDU-4821 题意:给定字符串S ,询问用几个子串满足 : 1.长度为n*len  . 2. n个子串都不相同. 题解:倒序hash将 ...

  7. 数据库SQL查询作业

    --设有三个关系 --S(S#,SNAME,AGE,SEX) --SC(S#,C#,GRADE) --C(C#,CNAME,TEACHER) --(1)检索LIU老师所授课程的课程号.课程名 sele ...

  8. python 查看模块中的方法

    way 1.help() way 2.dir() # dir() 函数不带参数时,返回当前范围内的变量.方法和定义的类型列表: way 3. 使用inspect模块, inspect.getmembe ...

  9. 从新建文件夹开始构建UtopiaEngine(1)

    序言 在苦等了半年多之后,我终于开始了向往已久的实时NPR游戏引擎项目--Utopia Engine,这半年多一直为了构建这个引擎在做很多准备:多线程.动态链接库.脚本引擎.立即渲染GUI--统统吃了 ...

  10. Python常用时间转换

    1 import time 2 import math 3 4 # 定义一些时间段的常量(秒) 5 TimeSec_Hour = 3600 6 TimeSec_Day = 86400 7 TimeSe ...