【题意】有k个整数数组,包含k个元素。在每个数组中取一个元素加起来,可以得到k^k个和。求这些和中最小的k个值(重复的值算多次)。

【解题方法】具体参见大白书P189.

【AC 代码】

//
//Created by just_sort 2016/9/16 11:08
//Copyright (c) 2016 just_sort.All Rights Reserved
//

#include <set>
#include <map>
#include <queue>
#include <stack>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int inf = 0x3f3f3f3f;
const int maxn = 755;
int A[maxn][maxn];
struct node{
    int s,b;
    node(int s,int b):s(s),b(b){}
    bool operator<(const node &rhs) const{
        return s>rhs.s;
    }
};
void Merge(int *A,int *B,int *C,int n)
{
    priority_queue<node>q;
    for(int i=0; i<n; i++){
        q.push(node(A[i]+B[0],0));
    }
    for(int i=0; i<n; i++){
        node cur=q.top();
        q.pop();
        C[i]=cur.s;
        int b = cur.b;
        if(b+1<n) q.push(node(cur.s-B[b]+B[b+1],b+1));
    }
}
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        for(int i=0; i<n; i++){
            for(int j=0; j<n; j++){
                scanf("%d",&A[i][j]);
            }
            sort(A[i],A[i]+n);
        }
        for(int i=1; i<n; i++)
            Merge(A[0],A[i],A[0],n);
        printf("%d",A[0][0]);
        for(int i=1; i<n; i++){
            printf(" %d",A[0][i]);
        }
        printf("\n");
    }
    return 0;
}