标签:
问题描述如下:
有k个整数数组,各包含k个元素。在每个数组中取一个元素加起来,可以得到k^k个和。求这些和中最小的k个值(重复计算的算多次)。
如果同时考虑这k个数组的取值情况,其复杂程度不言而喻,并且没有特别明确的递归约束关系,处理起来很棘手。
注意到在k^k个和中,我们只关心最小的k个和,题目暗示这是比寻找第k大的和简单的多的问题。
我们没有必要去枚举每一种取值情况,而只需要维护一些必要的数据。
考虑到每个数组能且只能取一个元素,因此我们可将求和的过程可以由之前的同时并发求和转化为当前的维护+优化。
就是说我们先考虑前k-1个数组,得到其最小的k个和,使其成为一个新的数组,考虑合并最后一个数组和该数组,显然有最终待求得k个
数必然被这k^2个数所包含。
假设我们将此问题记做L(k,k)问题,那么我们只需要考虑L(2,k),即有L(k,k) = (k - 1) * L(2,k)
记A[1...k], B[1...k],那么必然有
A[i] + B[p - i] <= A[j] + B[q - j], 其中q > p
即我们有A[1] + B[1] <= A[1] + B[2], A[2] + B[1] <= A[1] + B[3], A[2] + B[2], A[3] + B[1] <= ....
用优先队列维护之,合并两表代价为klogk
总的问题求解复杂度为k^2logk
题目有L(2,k)问题过渡到L(k,k)问题并无任何神奇之处,其中只用到了线性连续合并,问题复杂度的降低在于如何将并发枚举优化为维护更新。
标签:
原文地址:http://www.cnblogs.com/astoninfer/p/5430831.html