UVa 11997 K Smallest Sums/優先キュー
1335 ワード
ゆうせんキュー
n行各行n個の数字各行に1個の和を求める最小のn個を選択する
2行しかないとします
行ごとにソート
a1 a2 a3 ... an
b1 b2 b3 ... bn
a 1+b 1,a 2+b 1,a 3+b 1,...,an+b 1エンキュー
次に、最小(pop)を取り出し、ax+byであれば、n個を取り出して配列cに格納するまでax+b(y+1)(push)を入れる.
nがあれば、最初の行と2番目の行を2つマージした結果を3番目の行とマージできます...
n行各行n個の数字各行に1個の和を求める最小のn個を選択する
2行しかないとします
行ごとにソート
a1 a2 a3 ... an
b1 b2 b3 ... bn
a 1+b 1,a 2+b 1,a 3+b 1,...,an+b 1エンキュー
次に、最小(pop)を取り出し、ax+byであれば、n個を取り出して配列cに格納するまでax+b(y+1)(push)を入れる.
nがあれば、最初の行と2番目の行を2つマージした結果を3番目の行とマージできます...
#include <cstdio>
#include <queue>
#include <cstring>
#include <algorithm>
const int maxn = 800;
using namespace std;
int a[maxn][maxn];
struct Item
{
int s;
int b;
Item(int s, int b):s(s), b(b) {}
bool operator < (const Item& rhs) const
{
return s > rhs.s;
}
};
int n;
void merge(int* A, int* B, int* C)
{
priority_queue <Item> q;
for(int i = 0; i < n; i++)
q.push(Item(A[i]+B[0], 0));
for(int i = 0; i < n; i++)
{
Item item = q.top();
q.pop();
C[i] = item.s;
int b = item.b;
if(b+1 < n)
q.push(Item(item.s-B[b]+B[b+1], b+1));
}
}
int main()
{
int i, j;
while(scanf("%d", &n) == 1)
{
for(i = 0; i < n; i++)
{
for(j = 0; j < n; j++)
scanf("%d", &a[i][j]);
sort(a[i], a[i]+n);
}
for(i = 1; i < n; i++)
merge(a[0], a[i], a[0]);
printf("%d",a[0][0]);
for(i = 1; i < n; i++)
printf(" %d", a[0][i]);
printf("
");
}
return 0;
}