poj 2442(堆的stl实现)

来源:互联网 发布:职业摄影师知乎 编辑:程序博客网 时间:2024/05/16 15:46
Sequence
Time Limit: 6000MS Memory Limit: 65536KTotal Submissions: 6281 Accepted: 1962

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

12 31 2 32 2 3

Sample Output

3 3 4

Source

POJ Monthly,Guang Lin


首先要深入理解题意:

输入是m行*n列的矩阵。需要从每一行选一个数字,这样会构成m个数字的序列。

对这个序列求和,问最小的n个和是什么。


首先,要深刻理解,我们需要维护多少个数字。因为题目中只要求前n个最小和,我们只需要每步维护n个最小的数字即可。

比如第一行和第二行各挑一个数字求和,可以形成n*n个数字,排个序后,我们只需要保存前n个数字即可,根本不用管其余的数。第三行和上一步形成的这n个数字分别求和,又形成了n*n个数字,排个序后,再只保存前n个数字即可。因此可以逐步迭代计算。


如果按照上面的方法,写一个朴素的暴力算法,则空间复杂度为n*n,时间复杂度为(n*n + n*log(n)) * m 。可是TLE了。。



需要优化。想到用堆。因为事实上我们每步都只需要维护最小的n个数即可。那我们就维护一个大跟堆(注意这里是大跟堆),这个堆含有固定的n个元素(意味着初始化的时候,堆中有n个元素。以后只要插入一个元素,就要删除一个元素来保证堆中元素数目恒定为n)。
这个思路有了以后,再细想一下步骤:每一步先把thisline[0] 和 [lastheap[0], lastheap[n-1]] 分别相加,形成n个数字,建堆thisheap。再用[thisline[1]-thisline[n-1]]与[lastheap[0], lastheap[n-1]]分别求和,依次与thisheap的堆顶(最大值)比较,如果发现比最大值大,则舍弃。发现比最大值小,则删除堆中最大值,将新值push到堆中。

堆的几个重要的stl操作:
stl中的堆都是 大根堆
make_heap(v.begin(), v.end()); 将n个元素的数组建堆
pop_heap(v.begin(), v.end()); 将n个元素的堆的堆顶pop掉。此时数组中的0-n-2是一个有n-1个元素的新堆。被pop掉的原堆顶元素被放到了n-1的位置。因此往往在这一步之后还需要执行 v.pop_back();
push_heap(v.begin(), v.end()); 这一步首先要确保数组中的0-n-2是一个有n-1个元素的堆,而且新元素已经被放置在了v[n-1]位置。调用这个操作会将v[n-1] shiftup到合适的位置。因此在这一步之前要先执行v.push_front(x);
这么做的话,ac需要2600ms+, 如果加一个小小的优化:将thisline先排序,当发现求和大于堆顶元素时,后面的就都不用比较了。这么优化可以400+ms AC。
代码如下:

原创粉丝点击