题意:每行都必须取一个值,然后相加得到sum,求出前K个最小的sum。
/*
工具:优先队列
思想:
3
1 8 5
9 2 5
10 7 6
每一行都sort排序。
然后优先队列先存储1 5 8 分别 + 2 的值,其值为:3 7 10。
后面再是用1 分别和5 9 相加,如果在这途中没有比队列里
的值更小的值,那么就break掉,因为后面没有值可以更新优先队列里
的值了。就这样每行每行依次做下去。
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
const int maxn = 800;
using namespace std;
int n;
int s[maxn][maxn],cun[maxn];
priority_queue<int>q;//默认从大到小排序
void solve(int a,int b){
for(int i = 0 ; i < n ; i++){
q.push(s[a][i] + s[b][0]);
}
for(int i = 0 ; i < n ; i++){
for(int j = 1 ; j < n ; j++){
int kk = s[a][i] + s[b][j];
int kt = q.top();
q.pop();
if(kk < kt){
q.push(kk);
}
else{
q.push(kt);
break;
}
}
}
int cas = 0;
while(!q.empty()){
cun[cas] = q.top();
q.pop();
cas++;
}
for(int i = cas - 1 ,j = 0; i >= 0 ; i--){
s[b][j] = cun[i];
j++;
}
}
int main(){
while(~scanf("%d",&n)){
for(int i = 0 ; i < n ; i++){
for(int j = 0 ; j < n ; j++){
scanf("%d",&s[i][j]);
}
sort(s[i],s[i] + n);
}
for(int i = 0 ; i < n - 1 ; i++){
solve(i,i+1);
}
for(int i = n - 1 ; i >= 0 ; i--){
printf("%d%c",cun[i],i == 0?'\n':' ');
}
}
return 0;
}