Sequence
Time Limit: 6000MS |
Memory Limit: 65536K |
|
Total Submissions: 4906 |
Accepted: 1490 |
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
Source
POJ Monthly,Guang Lin
解题报告:这道题的题意是给我们m, n,下面有m行,每行有n个数,让我们求出前n个最小组合的和,共有n ^ m种的组合,但是只是让我们求出前n组即可,思路就是利用堆的性质,在遍历求和的同时调整堆;用的是STL写的
代码如下:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int MAX = 2010; int a[MAX], b[MAX], heap[MAX]; int main() { int i, j, m, n, t, flag; scanf("%d", &t); while (t --) { scanf("%d%d", &m, &n); for (i = 0; i < n; ++i) { scanf("%d", &a[i]); } sort(a, a + n);//将数组a按从小到大排序 while (-- m) { for (i = 0; i < n; ++i) { scanf("%d", &b[i]); } sort(b, b + n);//将数组b按从小到大排序 for (i = 0; i < n; ++i) { heap[i] = a[i] + b[0]; } make_heap(heap, heap + n);//make_heap 是按照给定的排序准则,把“最大”的元素排列到首位,而其他元素看上去并非有序: //相当于建立大顶堆 // 例如:输入 5个数 2 4 6 5 3 经历操作是 6 5 4 2 3 for (i = 1; i < n; ++i) { flag = 0; for (j = 0; j < n; ++j) { int temp = b[i] + a[j]; if (temp < heap[0]) { //pop_heap()不是真的把最大(最小)的元素从堆中弹出来。而是重新排序堆 //它把0和i个元素交换,然后将[0,i)的数据再做成一个大顶堆堆。 pop_heap(heap, heap + n); heap[n - 1] = temp; //push_heap()假设由[0,i)是一个有效的堆, //然后,再把堆中的新元素加进来,做成一个堆。 push_heap(heap, heap + n); flag = 1; } else { break;//当前已经是最小了 } } if (flag == 0) { break;//已经求出前n个最小的组合的和了 } } for (i = 0; i< n; ++i) { a[i] = heap[i]; } sort(a, a + n);//重新排序 } for (i = 0; i < n - 1; ++i) { printf("%d ", a[i]); } printf("%d\n", a[n - 1]); } return 0; }