您的位置:首页 > 其它

poj 2442(堆的stl实现)

2013-11-01 21:51 281 查看
Sequence

Time Limit: 6000MSMemory Limit: 65536K
Total Submissions: 6281Accepted: 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
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个最小的数字即可。

比如第一行和第二行各挑一个数字求和,可以形成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。

代码如下:
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: