MinimumMergeCost - 最小合并代价

问题

将长度为nn的序列s=[x1,x2,,xn]s = [x_{1}, x_{2}, \dots, x_{n}]进行合并,每次合并将相邻的两个元素aabb合并为一个新的元素cc,并且c=a+bc = a+b,合并的代价也为a+ba+b。经过n1n-1次合并后,序列ss被合并为1个数字,这个过程的代价是之前所有合并的代价总和。求出将序列ss合并为一个数字的最小合并代价。合并过程如图:

例如序列s=[1,2,3]s = [1,2,3],合并过程有[1,2,3][3,3][6][1,2,3] \rightarrow [3,3] \rightarrow [6][1,2,3][1,5][6][1,2,3] \rightarrow [1,5] \rightarrow [6],最终合并代价为9,119, 11

解法

sum(i,j)sum(i,j)为序列中区域s[i,j]s[i,j]的所有元素之和,f(i,j)f(i,j)为合并区域s[i,j]s[i,j]的最小代价,其中1ijn1 \leq i \leq j \leq n。因此有如下状态转移方程:

f(i,j)={0(initialize)i,j[0,n]i=j+(initialize)i,j[0,n]ijmin{f(i,k)+f(k+1,j)+sum(i,k)+sum(k+1,j)}(loop)i,j,k[1,n]ikjf(i,j) = \begin{cases} 0 & (initialize) & i,j \in [0,n] & i = j \\ +\infty & (initialize) & i,j \in [0,n] & i \neq j \\ min \{⁡f(i,k)+f(k+1,j)+sum(i,k)+sum(k+1,j) \} & (loop) & i,j,k \in [1,n] & i \leq k \leq j \end{cases}

(1)(1) 初始化,对于同一个元素s[i,i]s[i,i]不需要合并,因此f(i,i)=0f(i,i) = 0

(2)(2) 初始化,对于不同的元素s[i,j]s[i,j]需要合并,设未知的f(i,j)=+f(i,j) = +\infty

(3)(3)s[i,k]s[i,k]s[k+1,j]s[k+1,j]这两个区域的元素合并(ikji \leq k \leq j),因此f(i,j)=min{f(i,k)+f(k+1,j)+sum(i,k)+sum(k+1,j)}f(i,j) =min \{ f(i,k)+f(k+1,j)+sum(i,k)+sum(k+1,j) \},选择该范围中所有结果的最小值即可;

f(1,n)f(1,n)即为序列ss的最小合并代价。该算法的时间复杂度是O(n2)O(n^2)

石子合并

源码

MinimumMergeCost.h

MinimumMergeCost.cpp

测试

MinimumMergeCostTest.cpp

Last updated