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。
代码如下:
- poj 2442(堆的stl实现)
- STL的 heap 堆实现
- POJ 2442 Sequence 堆的思想的应用 STL 堆学习
- poj 2442【堆应用+STL Heap】
- 【堆】二分堆的实现以及STL中的堆
- POJ 2442 Sequence(stl+优先队列||堆)
- STL的堆操作
- STL的堆操作
- 用STL实现堆容器
- 仿STL中的堆算法的一个实现
- 仿STL中的堆算法的一个实现
- 仿STL中的堆算法的一个实现
- 二叉堆,堆排序,STL优先队列的底层实现,剑指offer数据流中的中位数
- STL 最大堆、最小堆的应用
- STL里面的堆操作
- C++ STL 堆的算法
- STL 堆heap的用法
- STL中的堆的使用方法
- what is IDE insight
- cd_old
- HDU 2065 "红色病毒"问题
- Linux环境变量的设置和查看方法
- UVA10134- Solve It
- poj 2442(堆的stl实现)
- poj 1442(两个优先队列)
- poj1426
- bootstrap3-validation表单验证
- poj 2513(trie树+并查集+欧拉回路条件)(记得要初始化指针数组)
- HDU1013
- .Net在线付款---Paydollar在线付款开发过程
- ubuntu下android开发环境搭建(eclipse+ADT+android sdk)
- OC语法之NSArray数组