题意:
给你m*n的矩阵问每行取一个数构成一个含m个数的序列,求序列和最小的前n个序列的和
分析:
对于m等于一的情况那么显然降序输出第一行的数就是答案
对于m等于二的情况:先读入第一行数据到一个堆中(堆的大小一直保持在n)
对于第二行的数据:先把堆中的数取出来记为a【】;
开始读入第二行的数据记为b【】;
如果读入的是b【0】那么把a【k】+b【0】压入堆中
如果读入的是b【j】0<j<m那么判断a【k】+b【j】与堆中最大的数相比如果小就更新堆
这样操作后堆中会留下最小的n个数(a【】+b【】)
那么当m为三的情况下我们可以视前面二行得到答案为一行那么就可以把问题转为一个已经解决过的问题惹
依次类推可以解决m为M的情况
ACcode:
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <queue>
using namespace std;
#define maxn 100007
int a[2005];
int main(){
int loop,n,m;
scanf("%d",&loop);
while(loop--){
scanf("%d%d",&m,&n);
priority_queue<int>q;
memset(a,0,sizeof(a));
int tmp;
for(int i=1;i<=n;++i){
scanf("%d",&tmp);
q.push(tmp);
}
for(int i=1;i<m;++i){
for(int j=1;j<=n;++j){
a[j]=q.top();
q.pop();
}
for(int j=1;j<=n;++j){
scanf("%d",&tmp);
for(int k=n;k>0;k--){
if(j==1)q.push(tmp+a[k]);
else{
if(tmp+a[k]<=q.top()){
q.push(tmp+a[k]);
q.pop();
}
else
break;
}
}
}
}
for(int i=1;i<=n;++i){
a[i]=q.top();
q.pop();
}
for(int i=n;i>0;--i)printf("%d%c",a[i],i==1?'\12':' ');
}
return 0;
}