zoukankan      html  css  js  c++  java
  • 《k路并归问题》

    模型一:给定n个数组,让你求n个数组中最小的k个数。

    这里显然可以用到一种贪心的维护思路。利用小顶堆。

    先将n个数组排成有序数组。

    将每个数组的最小的那个数放入小顶堆中。

    然后我们开始维护,很显然对于某一个数组中的某个数,如果它要被放入在小顶堆中,那他在该数组中前面位置的那个数,显然已经在队列中。

    因为它前面的那个数比他小,按照最小的思路,肯定是先放入最小的。

    模型二:UVA - 11997

    给定k个数组,每个数组中有k个数,求在每个数组中选一个数,组成的和的最小的k个。

    考虑递推的思路,假定我们当前维护到了第i个数组,且我们知道了前i - 1个数组每个取一个组成的最小k种方案。

    那么我们就可以转移过来。转移的思路依旧考虑有序数组,我们先用第i个数组的最小的数和前k个最小的组成新的k个数。

    放在小顶堆中,然后我们依旧用上面的维护思路,假定我们要变动的数在数组中的位置为p,那么下一个放入的肯定是p + 1和当前的组合。

    所以要记录下下标。

    // Author: levil
    #include<iostream>
    #include<stdio.h>
    #include<queue>
    #include<algorithm>
    #include<math.h>
    #include<stack>
    #include<map>
    #include<limits.h>
    #include<vector>
    #include<string.h>
    #include<string>
    using namespace std;
    typedef long long LL;
    typedef unsigned long long ULL;
    typedef pair<int,int> pii;
    const int N = 1e5 + 5;
    const int M = 1e7 + 5;
    const LL Mod = 1e9 + 7;
    #define pi acos(-1)
    #define INF 1e12
    #define dbg(ax) cout << "now this num is " << ax << endl;
    namespace FASTIO{
        inline LL read(){
            LL x = 0,f = 1;char c = getchar();
            while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();}
            while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();}
            return x*f;
        }
    }
    using namespace FASTIO;
    
    vector<int> vec[1005];
    LL ans[1005];
    int main() {
        int k;
        while(~scanf("%d",&k)) {
            for(int i = 1;i <= k;++i) {
                vec[i].clear();
                for(int j = 1;j <= k;++j) {
                    int x;scanf("%d",&x);
                    vec[i].push_back(x);
                }
                sort(vec[i].begin(),vec[i].end());
            }
            for(int i = 1;i <= k;++i) ans[i] = vec[1][i - 1];
            for(int i = 2;i <= k;++i) {
                priority_queue<pii,vector<pii>,greater<pii> >Q;
                for(int j = 1;j <= k;++j) {
                    Q.push(pii{ans[j] + vec[i][0],0});
                }
                for(int j = 1;j <= k;++j) {
                    LL val = Q.top().first;
                    int pos = Q.top().second;
                    Q.pop();
                    if(pos + 1 < k) Q.push(pii{val - vec[i][pos] + vec[i][pos + 1],pos + 1});//删去p,与p + 1组合
                    ans[j] = val;
                }
            }
            for(int i = 1;i <= k;++i) printf("%lld%c",ans[i],i == k ? '
    ' : ' ');
        }
    
        system("pause");
        return 0;
    }
    View Code
  • 相关阅读:
    linux 硬盘满了 怎么优化
    Mysql 忘记密码 Linux
    嵌入式新闻早班车-第18期
    《安富莱嵌入式周报》第225期:2021.08.09--2021.08.15
    【DSP教程】第43章 IIR滤波器的Matlab设计
    【DSP教程】第42章 IIR无限冲击响应滤波器设计
    嵌入式新闻早班车-第17期
    《安富莱嵌入式周报》第224期:2021.08.02--2021.08.08
    H7-TOOL重大更新,发布WiFi版,新增暗黑主题,脱机烧录增加大唐半导体,自此高速USB,以太网和WiFi方式全部打通(2021-08-07)
    【STM32H7的DSP教程】第41章 FIR滤波器的群延迟(重要)
  • 原文地址:https://www.cnblogs.com/zwjzwj/p/15024127.html
Copyright © 2011-2022 走看看