zoukankan      html  css  js  c++  java
  • 洛谷 P1631 序列合并(优先队列)

    传送门


    解题思路

    首先读入a、b数组后,sort一遍(从小到大),然后把a[1]+b[1],a[2]+b[1],a[3]+b[1]……a[n]+b[1]全部加入一个优先队列q(小根堆)。

    然后从一到n循环,每一次取出队列中的最小的元素(假设是a[i]+b[j]),输出数值,然后把数值修改为a[i]+b[j+1],存入队列。

    为什么呢?

    很显然,我们把所有可能的情况列成一张表:

    a[1]+b[1],a[2]+b[1],a[3]+b[1],……,a[n]+b[1];

    a[1]+b[2],a[2]+b[2],a[3]+b[2],……,a[n]+b[2];

    …………………………………………………………;

    a[1]+b[n],a[2]+b[n],a[3]+b[n],……,a[n]+b[n]。

    很显然,在这张表中,对于每一个数都一定小于它右下方的所有的数。

    换一种说法,就是在第[i,j]个数为成为当前最小值时,它右下方的数不可能成为当前最小值。

    所以只有在第[i,j]个数成为当前最小值时,把第[i+1][j]加入队列,继续比较。(也就是纵向更新)。

    AC代码

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstdio>
     4 #include<queue>
     5 using namespace std;
     6 const int maxn=100005;
     7 int n,a[maxn],b[maxn];
     8 struct node{
     9     int ans,bb;
    10     bool operator < (const node &x)const{
    11         return ans>x.ans;
    12     }
    13 };
    14 priority_queue<node> q;
    15 int main()
    16 {
    17     cin>>n;
    18     for(int i=1;i<=n;i++) cin>>a[i];
    19     for(int i=1;i<=n;i++) cin>>b[i];
    20     sort(a+1,a+n+1);
    21     sort(b+1,b+n+1);
    22     for(int i=1;i<=n;i++){
    23         node x;
    24         x.ans=a[i]+b[1];
    25         x.bb=1;
    26         q.push(x);
    27     }
    28     for(int i=1;i<=n;i++){
    29         node now=q.top();
    30         q.pop();
    31         cout<<now.ans<<" ";
    32         now.bb++;
    33         now.ans=now.ans+b[now.bb]-b[now.bb-1];
    34         q.push(now);
    35     }
    36     return 0;
    37 }
  • 相关阅读:
    mysql binlog日志删除
    在fork的项目里同步别人新增分支的方法
    Java中运算导致的基本数据类型自动转型 int i ; System.out.println(false?i:'e') 引发的血案
    替换String中的
    mysql绿色版安装及授权连接
    数据初始化函数随笔
    git命令简单使用
    idea常用快捷键(对于新手不建议切换使用eclipse)
    mybatis分页插件PageHelper简单应用
    mybatis处理LIKE模糊查询字符串拼接
  • 原文地址:https://www.cnblogs.com/yinyuqin/p/12019883.html
Copyright © 2011-2022 走看看