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
  • 相关阅读:
    Pycharm 设置python文件自动生成头部信息模板
    Python3.0 调用HTMLTestRunner生成的报告中不能显示用例中print函数的输出
    Python3.0 操作MySQL数据库执行SQL语句
    js时间戳转为日期格式
    Vue脚手架(vue-cli)安装总结
    Vue的生命周期
    常用的ES6语法
    学习python登录demo
    CSS的垂直居中和水平居中总结
    CSS清除浮动方法总结
  • 原文地址:https://www.cnblogs.com/zwjzwj/p/15024127.html
Copyright © 2011-2022 走看看