四边形不等式优化石子合并

关于四边形不等式或石子合并的资料。网上有很多。但有不少都是语焉不详,直接抛给你几个结论,让人很难理解。这篇文章将以石子合并为例。证明关于四边形不等式的一些结论。算是一个温习。

【题面】

      在一个操场上摆放着一排n(n≤20)堆石子。现要将石子有次序地合并成一堆。规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分。

试编程求出将n堆石子合并成一堆的最小得分和最大得分以及相应的合并方案。

【算法分析】

         下面只讨论最小得分的情况,最大得分的情况类似。

         设

f[I,j]=min{f[I,k]+f[k+1,j]+w[I,j]}{i<=k<j},特别的,f[I,i]=0。

         很明显,这是一个O(n^3)的动规

【算法优化】

         下面是重头戏。

         首先给出两个定义:

         (1)当函数w[i,j]满足w[i,j]+w[i',j']<=w[i',j]+w[i,j'],i<=i'<=j<=j'时,称w满足四边形不等式。

         (2)当函数w[i,j]满足w[i’,j]≤w[i,j’],i<=i'<=j<=j' 时称w关于区间包含关系单调。

       很明显的,一开始定义的w[I,j]满足区间包含关系和四边形不等式。

        现在我们要证明f[I,j]=min{f[I,k]+f[k+1,j]+w[I,j]}{i<=k<j}也满足四边形不等式

        我们利用数学归纳法对四边形不等式中的区间长度进行归纳。

证明如下:

      当i=i’或j=j’时,不等式显然成立。由此可知,当l≤1时,函数f满足四边形不等式。

      下面分两种情形进行归纳证明:

      情形1:i<i’=j<j’

      在这种情形下,四边形不等式简化为如下的不等式:f[i,j]+f[j,j’] ≤f[i,j’]+0,设k=max{p| f[i,j’]=f[i,p-1]+f[p,j’]+w[i,j’] },再分两种情形k≤j或k>j。下面只讨论k≤j,k>j的情况是类似的。

      情形1.1:k≤j,此时:

      情形1.2:k>j,略去

      情形2:i<i’<j<j’

      设 y=max{p | f[i’,j]=f[i’,p-1]+f[p,j]+w[i’,j] }

        z=max{p | f[i,j’]=f[i,p-1]+f[p,j’]+w[i,j’] }

       仍需再分两种情形讨论,即z≤y或z>y。下面只讨论z≤y,z>y的情况是类似的。

       情形2.1,i<z≤y≤j。

        显然的,我们有:

         f[i,j]+f[i',j']<=w[i,j]+f[i,z-1]+f[z,j]+w[i',j']+f[i',y-1]+f[y,j']

        因为w满足四边形不等式,所以:

        f[i,j]+f[i',j']<=w[i,j']+w[i',j]+f[i',y-1]+f[i,z-1]+f[z,j]+f[y,j']

        因为f[i,j']+f[i',j]=w[i,j']+w[i',j]+f[i',y-1]+f[i,z-1]+f[y,j]+f[z,j']

        所以,要证f[i,j']+f[i'j]>=f[i,j]+f[i',j'],就要证f[z,j]+f[y,j']<=f[y,j]+f[z,j']。

        因为i<z≤y≤j,所以区间的长度会在不断地迭代中越变越小,最后归于前面的几种情况。

        情形2.1,i<y≤z≤j。证明过程略。

        综上所述,f[i,j]满足四边形不等式。

         事实上,对于任意f[I,j]=max{f[I,k]+f[k+1,j]+w[I,j]}{i<=k<j},如果w满足四边形不等式,那么f也满足四边形不等式。

         前面千辛万苦证明了f满足四边形不等式,那么它有什么用呢?

         之所以要证明四边形不等式,就是为了证明f满足决策单调性,即:

                        s[i,j-1]≤s[i,j]≤s[i+1,j],     i≤j

         其中,s[I,j]为区间[I,j]上的最优决策。

         当i=j时,单调性显然成立。因此下面只讨论i<j的情形。由于对称性,只要证明s[i,j]≤s[i,j+1]。

         令fk[i,j]=f[i,k-1]+f[k,j]+w[i,j]。要证明s[i,j]≤s[i,j+1],只要证明对于所有i<k≤k’≤j且fk’[i,j]≤fk[i,j],有:fk’[i,j+1]≤fk[i,j+1]。

         事实上,我们可以证明一个更强的不等式

fk[i,j]-fk’[i,j]≤fk[i,j+1]-fk[i,j+1]

         也就是:          fk[i,j]+fk’[i,j+1]≤fk[i,j+1]+fk’[i,j]

         利用递推定义式将其展开整理可得:f[k,j]+f[k’,j+1]≤f[k’,j]+f[k,j+1],这正是k≤k’≤j<j+1时的四边形不等式。

         综上所述,当w满足四边形不等式时,函数s[i,j]具有单调性。

         因此,我们可以得到一个更优化的转移方程:

改进后的状态转移方程所需的计算时间为

上述方法利用四边形不等式推出最优决策的单调性,从而减少每个状态转移的状态数,降低算法的时间复杂度。

这样这道题就解决了。

一般的,对于状态转移方程形如:f[i , j] = opt{f[i , k] + f[k+1 , j]} + w[i , j], i < j的动规,若w满足四边形不等式,则f满足四边形不等式,则f有决策单调性。


BY QW

转载请注明出处


四边形不等式是一种在动态规划优化中使用的重要理论,虽参考引用未提及相关内容,但下面将介绍其原理、应用及代码示例。 ### 原理 四边形不等式是指对于函数 $w(i, j)$,若对于任意的 $a \leq b \leq c \leq d$,都有 $w(a, d) + w(b, c) \geq w(a, c) + w(b, d)$ 成立,则称函数 $w$ 满足四边形不等式。在动态规划中,若状态转移方程 $dp[i][j] = \min_{i \leq k < j} \{dp[i][k] + dp[k + 1][j] + w(i, j)\}$ 中的 $w(i, j)$ 满足四边形不等式,那么 $dp[i][j]$ 也满足四边形不等式,并且可以证明决策点 $s[i][j]$ 具有单调性,即 $s[i][j - 1] \leq s[i][j] \leq s[i + 1][j]$,利用这一性质可以将动态规划的时间复杂度从 $O(n^3)$ 优化到 $O(n^2)$。 ### 应用 四边形不等式主要应用于动态规划的优化,常见的应用场景有: - **区间动态规划**:在处理区间合并、区间划分等问题时,若状态转移方程符合上述形式且 $w(i, j)$ 满足四边形不等式,就可以使用该优化方法。 - **最优二叉搜索树**:在构建最优二叉搜索树的过程中,通过四边形不等式可以优化动态规划的过程,减少不必要的计算。 ### 代码示例 以下是一个使用四边形不等式优化的动态规划代码示例,用于解决石子合并问题: ```java public class QuadrangleInequality { public static int stoneMerge(int[] stones) { int n = stones.length; int[] sum = new int[n + 1]; for (int i = 1; i <= n; i++) { sum[i] = sum[i - 1] + stones[i - 1]; } int[][] dp = new int[n + 1][n + 1]; int[][] s = new int[n + 1][n + 1]; for (int i = 1; i <= n; i++) { s[i][i] = i; } for (int len = 2; len <= n; len++) { for (int i = 1; i <= n - len + 1; i++) { int j = i + len - 1; dp[i][j] = Integer.MAX_VALUE; for (int k = s[i][j - 1]; k <= s[i + 1][j]; k++) { int temp = dp[i][k] + dp[k + 1][j] + sum[j] - sum[i - 1]; if (temp < dp[i][j]) { dp[i][j] = temp; s[i][j] = k; } } } } return dp[1][n]; } public static void main(String[] args) { int[] stones = {3, 2, 4, 1}; System.out.println("最小合并代价: " + stoneMerge(stones)); } } ``` 在上述代码中,`stoneMerge` 方法实现了石子合并问题的动态规划解法,并使用四边形不等式进行了优化。`sum` 数组用于记录前缀和,`dp` 数组用于记录状态,`s` 数组用于记录决策点。通过两层循环枚举区间长度和区间起点,在状态转移时利用决策点的单调性减少不必要的计算。
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值