您的位置:首页 > 其它

uva 11997 K Smallest Sums

2014-10-01 22:19 197 查看
首先对每行进行排序,并对与前两行有$A = a_1 \leq a_2 \leq \cdots \leq a_k$和$B = b_1 \leq b_2 \leq \cdots \leq b_k$。首先把所有的$b_i , i\in [1,k]$与$a_1$进行求和,并加入优先队列中。其中最小的必然是$a_1+b_1$,在优先队列队首。然后只需在优先队列中压入$a_1+b_2$,没有压入$a_2+b_1$原因是该和已经在队列中存在了,没有压入$a_2+b_2$的原因是$a_2+b_2 \leq a_1 + b_2$因此无需压入。

从而循环往复,对所有的k行都进行上面的操作。即可取出最小的k个和。

代码如下:

#include  <iostream>
#include  <queue>
#include  <string>
#include  <cstdio>
#include  <algorithm>
using namespace std;
int arr[800][800];
int k;
class node
{
public:
int num, sum;
node(int n, int s)
{
num = n;
sum = s;
}
bool operator < (const node & n)const
{
return sum > n.sum;
}

};
void merge(int *a, int *b, int *res, int k)
{
priority_queue<node> q;

node tmp(0,0);
for( int i = 0 ; i < k ; i++ )
{
tmp.sum = a[i] + b[0];
tmp.num = 0;
q.push(tmp);
}
for( int i = 0 ; i < k ; i++ )
{
tmp  = q.top();
res[i] = q.top().sum;
q.pop();
if(tmp.num + 1 < k)
{
tmp.sum = tmp.sum - b[tmp.num] + b[tmp.num+1];
tmp.num++;
q.push(tmp);
}
}
}
int main(int argc, char *argv[])
{
while( scanf("%d", &k ) != EOF)
{
for( int i = 0 ; i < k ; i++ )
{
for( int j = 0 ; j < k ; j++ )
{
scanf("%d", &arr[i][j]);
}
sort(arr[i], arr[i]+k);
}
for(int i = 1 ; i < k ; i++ )
merge(arr[0], arr[i], arr[0], k);
for(int i = 0 ; i < k ; i++ )
printf("%d%s",arr[0][i],i != k-1?" ":"\n");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: