【二叉哈弗曼树 序列问题】 Sequence

传送门

题意

\(m\)个序列,每个里面包含\(n\)个非0整数,
现在可以从每个序列中选择一个数字形成具有\(m\)个整数的序列
总共有\(n\times m\)种序列,计算每个序列中的数字之和,得到\(n^{m}\)个值,求这些序列和中的最小的\(n\)个值

数据范围

\(\begin{array}{l}0<m \leq 1000 \\ 0<n \leq 2000\end{array}\)

题解

\(m\)个里面每个选一个,输出最小的\(n\)个和
分组,每次都将两个的前\(n\)个看作是一个新的,同后面的一块计算,
求出前\(n\)小的作为新的一组,一直迭代最后求出的自然就是整个的前\(n\)小的

Code

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=a;i<b;i++)
#define fi first 
#define se second 
const int N=2010;
typedef pair<int,int> pii;
int n,m;
int _;
int a[N],b[N],c[N];

void solve()
{
    cin>>m>>n;
    rep(i,0,n) cin>>a[i];
    sort(a,a+n);
    rep(i,0,m-1)
    {   
        priority_queue<pii,vector<pii>,greater<pii>>heap;
        rep(i,0,n) cin>>b[i];
        rep(i,0,n) heap.push({a[0]+b[i],0});

        rep(i,0,n)
        {
            auto t = heap.top();
            c[i]=t.fi;
            int id=t.se; // 表示在原来序列中的下标
            heap.pop();
            heap.push({t.fi-a[id]+a[id+1],id+1});
        }
        rep(i,0,n) a[i]=c[i];
     }
    rep(i,0,n) cout<<a[i]<<' ';
    cout<<endl;
}
int main()
{
    cin>>_;
    while(_--) solve();
}
posted @ 2020-05-23 00:49  Hyx'  阅读(114)  评论(0)    收藏  举报