Description
Given m sequences, each contains n non-negative integer. Now we may select one number from each sequence to form a sequence with m integers. It's clear that we may get n ^ m this kind of sequences. Then we can calculate the sum of numbers in each sequence, and get n ^ m values. What we need is the smallest n sums. Could you help us?
Input
The first line is an integer T, which shows the number of test cases, and then T test cases follow. The first line of each case contains two integers m, n (0 < m <= 100, 0 < n <= 2000). The following m lines indicate the m sequence respectively. No integer in the sequence is greater than 10000.
Output
For each test case, print a line with the smallest n sums in increasing order, which is separated by a space.
Sample Input
1 2 3 1 2 3 2 2 3
Sample Output
3 3 4
由前两个数组里的任意两个数的和最小的前n个值再和第三个数组相加,去最小的n个,以此类推,就可以求出整个数组最小的。实际上每个最小的和都是在每一个数组中取一个元素相加。
#include <iostream> #include <algorithm> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #include <math.h> #include <ctype.h> #include <queue> #include <map> #define MAX 100007 using namespace std; int main() { priority_queue<int> q;//默认队列顶是最大值 int a[109][2009]; int b[2100]; int T,i,j,k,n,m; scanf("%d",&T); while(T--) { scanf("%d%d",&m,&n); for(i = 0; i < m; i++) { for(j = 0; j < n; j++) { scanf("%d",&a[i][j]); } sort(a[i],a[i]+n);//对每一个数组进行排序,保证前边的都是最小的 } for(i = 0 ; i < n ; i++) q.push(a[0][i]); for(i = 1; i < m; i++) { for(j = 0; j < n; j++) { b[j] = q.top(); q.pop(); } for(j = 0; j < n; j++) { for(k = n-1; k >= 0; k--) { if(j == 0) { q.push(a[i][j] + b[k]); } else { int he,bi; he = a[i][j] + b[k]; bi = q.top(); if(bi > he)//如果想加的和比最大值小,队顶删除,和进队列 { q.pop(); q.push(he); } else//负责,那么后面的相加就会更大,也就没有必要继续了,直接跳出 break; } } } } for(j = 0; j < n; j++) { b[j] = q.top(); q.pop(); } printf("%d",b[n-1]); for(i = n-2; i >= 0; i--) printf(" %d",b[i]); printf("\n"); } return 0; }