对于这个问题,首先按照《编程之美》中的分析对这个问题进行一定的简化。从2n个数中找n个元素,有三种可能:大于Sum/2,小于Sum/2以及等于Sum/2。而大于Sum/2与小于等于Sum/2没区别,故可以只考虑小于等于Sum/2的情况。

动态规划第一步,分析子问题:

这里我们用一个三维数组F[][][]表示子问题,F[i][j][k]表示前i个元素中选取j个元素,使得其和不超过k且最接近k。这个子问题可以根据第i个元素是否选择来进行分析:

跟着编程之美学算法——数组分割

如果我们想回溯找到一组合理的分割方式,那么在子问题的求解过程中,就要记录有效的路径,这样我们再用一个三维数组path[][][]来记录。

伪代码如下所示:

 1 F[][][] = 0
 2 path[][][] = 1
 3 
 4 for i = 1 to 2*N
 5     nLimit = min(i, N)
 6     for j = 1 to nLimit
 7         for k = 1 to sum/2
 8             F[i][j][k] = F[i-1][j][k]
 9             if k > A[i] && F[i-1][j-1][k-A[i]] + A[i] > F[i][j][k]
10                 F[i][j][k] = F[i-1][j-1][k-A[i]] + A[i]
11                 path[i][j][k] = 1
12 
13 return F[2N][N][sum/2], path[][][]
View Code

相关文章:

  • 2021-08-21
  • 2021-09-25
  • 2022-03-04
  • 2021-05-31
  • 2021-11-25
  • 2021-07-02
  • 2021-12-18
  • 2021-08-29
猜你喜欢
  • 2021-10-01
  • 2021-11-15
  • 2022-02-18
  • 2022-02-19
  • 2021-12-26
  • 2021-08-31
  • 2022-02-01
相关资源
相似解决方案