编程之美2.18——数组分割(动态规划问题)
题目概述:有一个没有排序,元素个数为2N的正整数数组。要求把它分割为元素个数为N的两个数组,并使两个子数组的和最接近。(啃了好久才啃明白,主要是动态规划可惜忘了,第一眼看不懂的童鞋洗洗睡睡明天继续研究哈,更多精彩请看《编程之美》) 第一想法: 是从2N个数的数组中提取所有N的组合情况,估计需要N个for循环,此时至少为N的阶乘的时间复杂度;然后想到动态规划的0-1背包(其实是看了原文才晓得的),将heap[M](M表示从2N中所有可能的M个元素和组成的集合),从下到上(m->1...->N)最终求的完整的heap[N]。要点:可以想成求 不大于sum/2的最接近集合, 以下为分析: 假设数组A[1..2N]所有元素的和是SUM。模仿动态规划解0-1背包问题的策略,令S(k, i)表示前k个元素中任意i个元素的和的集合。显然: S(k, 1) = {A[i] | 1<= i <= k} S(k, k) = {A[1]+A[2]+…+A[k]} S(k, i) = S(k-1, i) U {A[k] + x | x属于S(k-1, i-1) } 按照这个递推公式来计算,最后找出集合S(2N, N)中与SUM/2最接近的那个和,这便是答案。 第二想法: 第一种算法时间复杂度随着N的增大而“狠大”,注意是很大,所以出现了第三种方法(书上说时间复杂度为n的平方乘以num)