1855_Give you a Matrix

Give you a Matrix

  • Description

    给你k个数组,每个数组有k个元素,那么如果从每个数组里面取一个数出来,将有 k^k 种组合方式,我们计算每种方式中从每个数组中取出来的数的和(即取出来的k个数的和),现在我们需要知道这k^k个组合方式中的和中最小的k个和。

  • Input

    有多个测试用例。每个测试用例的第一行包含一个整数K(2 <= K<=750)。以下的K行都包含K个正整数。这些整数,每个都不超过1,000,000。输入文件到文件尾结束。输入文件的大小不超过5MB。

  • Output

    对于每个测试用例,以非降序的方式输出这k个最小值。

  • Sample Input

3
1 8 5
9 2 5
10 7 6
2
1 1
1 2

  • Sample Output

9 10 12
2 2

  • Hint

    对于测试用例2:有四种组合方式,和分别为2,2,3,3,其中最小的2个和为2,2.

 #include <iostream>
#include <algorithm>
#include <queue>
#include <cstdio>
#include <cstring>

using namespace std;
#define N 800
int a[N][N],n,tp[N];
struct cmp
{
    bool operator()(const int&a,const int&b)
    {
        return a<b;
    }
};
typedef priority_queue<int,vector<int>,cmp> pq;
pq q;

void input()
{
    while(!q.empty())   q.pop();
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        scanf("%d",&a[i][j]);
    }
}

void solve()
{
    for(int i=0;i<n;i++)    sort(a[i],a[i]+n);
    for(int i=0;i<n;i++)    tp[i]=a[0][n-i-1];

    for(int i=1;i<n;i++)
    {
        for(int j=0;j<n;j++)    q.push(a[i][0]+tp[j]);

        for(int j=1;j<n;j++)
        {
            if(a[i][j]+tp[n-1]>=q.top()) break;

            q.push(a[i][j]+tp[n-1]);
            int t=n/(j+1)+1;
            for(int k=n-2;n-k<=t;k--)
            {
                if(a[i][j]+tp[k]>=q.top())   break;
                q.push(a[i][j]+tp[k]);
            }
        }
        while(q.size()!=n)  q.pop();
        for(int j=0;j<n;j++)
        {
            tp[j]=q.top();
            q.pop();
        }
    }
    printf("%d",tp[n-1]);
    for(int i=n-2;i>=0;i--)
    {
        printf(" %d",tp[i]);
    }
    printf("\n");
}

int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        input();
        solve();
    }
    return 0;
}

你可能感兴趣的:(1855_Give you a Matrix)