Sequence(Poj2442)

题意:

有m个数列,每个数列n个值,每个序列中选取一个值可以组成n^m种不同的序列,求前n小的序列和。

Input

1
2 3
1 2 3
2 2 3

Output

3 3 4

分析:

用两个优先队列维护前n小和。首先将第一列n个数字放入从大到小的优先队列中,每次弹出一个最小值和下一行的每个元素相加,并放入另一个从小到大的优先队列中,当放满n个值时,每次求和结果先和队列中的top对比,若小于top则弹出并塞入这个和,否则舍弃这个较大和。这样维护的就是求和到第i行时的前n小序列和。当数列中n个元素都和下一列的元素求和完后,将这些前n小和又倒出来塞入从大到小的队列中,这样就和一开始对第一行的数列一样,每次选取一个最小值进行和后面的值求和,并将和塞入从小到大的优先队列中,这样反复倒腾最后加和到最后一行时仍然是所有数列求和的最小值,然后放入从大到小的数列中,依次弹出即是升序输出。


• 两组两组的看,首先要排序,然后从头开始找最小的N个和。

• 怎么找是个问题,对于第一组我们取i=1,第二组取j=1,然后a[1]+b[1]肯定是最小的,然后a[2]+b[1],a[1]+b[2]进入候选项,如果我们下一次选中了a[2]+b[1],那么我们又要将a[3]+b[1],a[2]+b[2]加入候选项。

• 但是我们要保证产生候选项不能重复,比如a[1]+b[2]和a[2]+b[1]都可以产生a[2]+b[2],所以我们要排除其中的一种,也就是说,我们要将候选项的下标计算变得有限制。

• 候选项的下标都是通过选中当前项的下标加一得到的,那么为了避免重复,我们要制定一种规则。假如规定为如果j+1,那么这个候选项被选中的时候i就不能更新。

  1. i=1,j=1

• 更新i=2,j=1, flag = true

• 更新i=1, j=2, flag = false

  1. 假如选中i=2,j=1,flag = true

• 由于是true,可以更新i=3,j=1,flag = true

• 更新i=2,j=2,flag = false

  1. 假如选中i=1,j=2,flag = false

• 由于false,不能更新i

• 更新i=1,j=3,flag = false

......

对于两个序列我们就可以a[0]+b[0],a[1]+b[0]一直到a[n-1]+b[0],然后是依次加a[1],这样我们就可以得到一个新的序列,如果只有两个序列,那我们的序列就是符合条件的,如果对于三个序列那就是两个序列组成的新序列看成新的a序列,第三个序列就是b序列,想一想,是不是?

这样依次迭代,到最后就是所求的m个序列组成的新序列,如果我们全部暴力存储,显然时间和空间开销都是非常大的,到最后跟直接m个序列暴力是没有区别的,达到n^m。 每次维护长为n的数组就可以啦



#include<stdio.h>///两个优先队列组合使用
#include<queue>
using namespace std;
int main()
{
int t,i,j,m,n,num;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&m,&n);
priority_queue<int ,vector<int>,less<int> >s;///一个优先级 从 小->大
priority_queue<int ,vector<int>,greater<int> >q;///一个优先级 从 大->小
for(i=1; i<=m; i++)///输入m列
{
if(i==1)///先将第一列作为基础塞入q队列中
{
for(j=0; j<n; j++)
{
scanf("%d",&num);
q.push(num);
}
}
else
{
int numd[n+10],sum;
for(j=0; j<n; j++)///几列,存入一个数组中
{
scanf("%d",&numd[j]);
}
while(q.size())///从q队列中,一个一个选出元素,分别与后面输入的数组中的每一个值相加
{
sum=q.top();///选出队首元素,记为sum
q.pop();///出列
for(j=0; j<n; j++)///和输入的数组中每个都加一遍
{
if(s.size()==n&&s.top()>sum+numd[j])///若超过或等于了n个元素,判断s队列中的队首(放入队列中的最大值)是否大于当前选出的数和数组中元素之和
{
s.pop();///若大于,弹出那个较大数,重新塞入求和而得的较小的数
s.push(sum+numd[j]);
}
else if(s.size()<n)///s队列中若没达到n个元素,加完就塞进去
{
s.push(sum+numd[j]);
}
}///这样一个循环下来,就将下一组数与当前q队列中的某一个元素相加完毕,并筛选出了前n个较小的求和数
}///while的下一轮将求和队列中的下一个数,并继续筛选求和数中的前n小值
while(s.size())///所有数筛选完毕此时在s队列中都是最小的前n个数
{
q.push(s.top());
s.pop();
}///每行完成更新后将求和结果统一塞回Q队列中准备下一行筛选求和
}
}
while(q.size())
{
printf("%d%c",q.top(),(q.size()-1==0)?'\n':' ');
q.pop();
}
}
return 0;
}

 

Sequence(Poj2442)的更多相关文章

  1. POJ2442 Sequence(堆的骚操作)

    Description Given m sequences, each contains n non-negative integer. Now we may select one number fr ...

  2. POJ-2442 Sequence K路归并问题

    题目链接:http://poj.org/problem?id=2442 问题一:K个有序表合成一个有序表,元素共有n个.用堆优化 问题二:两个序列的前n小的元素.堆优化. 这题就是问题二的扩展,每次处 ...

  3. POJ2442 Sequence

    题目链接. #include <iostream> #include <cstdio> #include <cstring> #include <cstdli ...

  4. POJ2442:Sequence

    浅谈堆:https://www.cnblogs.com/AKMer/p/10284629.html 题目传送门:http://poj.org/problem?id=2442 我们先简化题意,假设只有两 ...

  5. $POJ2442\ Sequence$ 堆

    正解:堆 解题报告: 传送门$QwQ$ 全场除了我都切了系列$kk$ 首先看$n=2$的情况. 首先暴力不说?就记录一个$sum$再分别记录$xy$两维的下标存到堆里面每次取队头并继续扩展就完事$Qw ...

  6. oracle SEQUENCE 创建, 修改,删除

    oracle创建序列化: CREATE SEQUENCE seq_itv_collection            INCREMENT BY 1  -- 每次加几个              STA ...

  7. Oracle数据库自动备份SQL文本:Procedure存储过程,View视图,Function函数,Trigger触发器,Sequence序列号等

    功能:备份存储过程,视图,函数触发器,Sequence序列号等准备工作:--1.创建文件夹 :'E:/OracleBackUp/ProcBack';--文本存放的路径--2.执行:create or ...

  8. DG gap sequence修复一例

    环境:Oracle 11.2.0.4 DG 故障现象: 客户在备库告警日志中发现GAP sequence提示信息: Mon Nov 21 09:53:29 2016 Media Recovery Wa ...

  9. Permutation Sequence

    The set [1,2,3,-,n] contains a total of n! unique permutations. By listing and labeling all of the p ...

随机推荐

  1. source insight4提示结尾不一致。关闭

    source insight4提示结尾不一致.关闭.世界清静了. Options -> Preferences ->Files  最后的Ask to fix inconsistent li ...

  2. Python数据清洗:提取爬虫文本中的电话号码

    步骤索引 效果展示 注意事项 代码 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手.很多已经做案例的人,却不知道如何去学习更加高深的知识. ...

  3. 牛顿迭代法解非线性方程组(MATLAB版)

    牛顿迭代法,又名切线法,这里不详细介绍,简单说明每一次牛顿迭代的运算:首先将各个方程式在一个根的估计值处线性化(泰勒展开式忽略高阶余项),然后求解线性化后的方程组,最后再更新根的估计值.下面以求解最简 ...

  4. [BUUOJ记录] [ACTF2020 新生赛]Include

    本题主要考查了利用php://filter伪协议进行文件包含 进入题目根据Tip进入正题,可以看到URL中存在文件包含(题目名也很直接) 首先考虑 "php://input"伪协议 ...

  5. vue mixin混入

    基本结构 export default { data() { return {} }, computed: { }, methods: { }, filters: { }, created() { } ...

  6. npm 进阶命令知多少(一)

    npm命令知多少(一) 前言 作为前端模块化扎展现形式的npm包,已经在前端开发中不可或缺,熟练掌握npm相关内容,也是前端开发者的一门必修课,那么除了npm publish这类常见内容之外,还有哪些 ...

  7. Mysql批量导入

    这应该是我写Mysql技术的最后一章了吧,短时间内应该不会再写Mysql的文章了,当然疑难杂症除外 insert语句优化 因为之前我也遇到过这样的问题,是我在做数据库适配的时候碰见的,那是我的数据还是 ...

  8. python基础 画图

    python 画图 matplotlib 库只保存图片,不显示图片? 在导入库时,添加如下代码 import matplotlib matplotlib.use('Agg')  各种 symbol ? ...

  9. Linux:安装php

    一.环境准备(lamp环境:linux+apache+php+mysql) 1.安装php之前,首先要检查一下相关lib库 rpm -qa  zlib libxml libjpeg freetype ...

  10. [LeetCode]1084. 销售分析III(Mysql,having+聚合函数)

    题目 Table: Product +--------------+---------+ | Column Name | Type | +--------------+---------+ | pro ...