C++ 降低阵列最大最小和2-划分的时间复杂度

C++ 降低阵列最大最小和2-划分的时间复杂度,c++,algorithm,recursion,dynamic-programming,C++,Algorithm,Recursion,Dynamic Programming,让array[N]一个N非负值数组。我们试图递归地将数组划分为两(2)个子数组,这样我们就可以实现每个子数组的最大“最小和”。解决方案由以下递归描述: 我们要计算opt[0][N-1] 让c[x][y]表示从x到y的sum{array[i]}(包括)。 我已经成功地使用下面的C++程序片段解开递归,使用动态编程: for ( uint16_t K1 = 0; K1 < N; K1 ++ ) { for ( uint16_t K2 = 0; K2 < N-K1; K2 ++

array[N]
一个
N
非负值数组。我们试图递归地将数组划分为两(2)个子数组,这样我们就可以实现每个子数组的最大“最小和”。解决方案由以下递归描述:

我们要计算
opt[0][N-1]

c[x][y]
表示从
x
y
sum{array[i]}
(包括)。 我已经成功地使用下面的C++程序片段解开递归,使用动态编程:

for ( uint16_t K1 = 0; K1 < N; K1 ++ ) {
    for ( uint16_t K2 = 0; K2 < N-K1; K2 ++ ) {

        const uint16_t x = K2, y = K2 + K1;
        opt[x][y] = 0;

        for ( uint16_t w = x; w < y; w ++ ) {

            uint32_t left  = c[x][w]   + opt[x][w];
            uint32_t right = c[w+1][y] + opt[w+1][y];

            /* Choose minimum between left-right */
            uint32_t val = MIN( left, right );

            /* Best opt[x][y] ? */
            if ( val > opt[x][y] ) {
                opt[x][y] = val;
            }
        }

    } /* K2 */
}     /* K1 */
(uint16_t K1=0;K1{ 对于(uint16_t K2=0;K2opt[x][y]){ opt[x][y]=val; } } }/*K2*/ }/*K1*/ 此技术解析所有子阵列,从大小
1
到大小
N
。因此,最终溶液将存储在
opt[0][N-1]

例如,如果
N=6
,矩阵将按如下方式迭代:
(0,0)(1,1)(2,2)(3,3)(4,4)(5,5)(0,1)(1,2)(2,3)(3,4)(4,5)(0,2)(1,3)(2,4)(3,5)(0,3)(1,4)(2,5)(0,4)(1,5)(0,5)
。最终答案将出现在
opt[0][5]

我已经测试并验证了上面的技术可以解除递归。我试图进一步降低复杂性,因为如果我是正确的,这将在O(n^3)中运行。这能实现吗


编辑:我还注意到递归的物理意义,正如在评论中所问的那样。让
N
表示跨越直线的
N
城市。我们是控制这些城市的地主;在一年的,每个城市
i
只要在我们的控制下,就会支付
array[i]
硬币的维护费


我们的城市正受到优势部队的攻击,失败是不可避免的。每年年初,我们在两个相邻的城市之间筑起一堵墙,
i
i+1
x以下是问题的最终答案,请参考@NiklasB.。让
w(x,y)
表示问题
opt[x][y]
的数组的最佳分区。如下所示,
x这类似于矩阵乘法中的dp,它在这里不起作用,因为你试图将一个集合分成两个子集合,并且总和尽可能接近相等。我说得对吗?这看起来不像是一个已知的多项式时间解。@n.m如果子集必须是连续的,这并不难,就像在这种情况下。而且复发看起来比以前更复杂that@NiklasB对不起,我没听懂。这与集合划分或子集和问题有何不同?FWIW,让w(x,y)是opt(x,y)定义中的最优w。我猜想在所有情况下都有一个w(x,y+1)>=w(x,y)的解,并且你的递归的右边在w中是凸的。这使您可以通过固定x,然后按递增顺序计算y,从而去除时间复杂度中n的一个因子,得到O(n^2)。作为参考,Donald Knuth讨论了此类优化,后来Yao在
for ( uint16_t w = wall[x][y-1]; w <= wall[x+1][y]; w ++ ) {
  ...
  if ( val > opt[x][y] ) {
    opt[x][y] = val;
    wall[x][y] = w;
  }
}