Java中的四边形不等式优化
四边形不等式(Quadrilateral Inequality, QI)是一种在动态规划优化中常用的技术,特别是在区间DP问题中。它可以帮助减少状态转移的计算量,从O(n³)优化到O(n²)。
四边形不等式的基本概念
对于函数w(l, r)(通常表示区间[l, r]的代价),如果满足:
w(a, c) + w(b, d) ≤ w(a, d) + w(b, c) (对于a ≤ b ≤ c ≤ d)
则称w满足四边形不等式。
在动态规划中的应用
在区间DP中,如果状态转移方程为:
java
dp[i][j] = min/max(dp[i][k] + dp[k][j] + w(i, j)) (i ≤ k < j)
当w满足四边形不等式时,dp也满足四边形不等式,且最优决策点具有单调性。
Java实现示例
1. 检查四边形不等式
java
// 检查函数w是否满足四边形不等式
public static boolean checkQuadrilateralInequality(int[][] w, int n) {
for (int a = 0; a < n; a++) {
for (int b = a; b < n; b++) {
for (int c = b; c < n; c++) {
for (int d = c; d < n; d++) {
if (w[a][c] + w[b][d] > w[a][d] + w[b][c]) {
return false;
}
}
}
}
}
return true;
}
2. 使用四边形不等式优化的区间DP
java
public class QuadrilateralInequalityOptimization {
static int[][] dp;
static int[][] s; // 记录决策点
static int[][] w; // 代价函数
public static void solve(int n) {
dp = new int[n][n];
s = new int[n][n];
// 初始化
for (int i = 0; i < n; i++) {
dp[i][i] = 0; // 或根据问题初始化
s[i][i] = i;
}
for (int len = 2; len <= n; len++) {
for (int i = 0; i + len - 1 < n; i++) {
int j = i + len - 1;
dp[i][j] = Integer.MAX_VALUE;
// 利用单调性缩小k的范围
for (int k = s[i][j-1]; k <= s[i+1][j]; k++) {
if (k >= j) continue;
int cost = dp[i][k] + dp[k+1][j] + w[i][j];
if (cost < dp[i][j]) {
dp[i][j] = cost;
s[i][j] = k;
}
}
}
}
}
}
常见应用场景
- 最优二叉搜索树问题
- 矩阵链乘法
- 多边形三角剖分
- 文件合并问题
优化效果
- 未优化:O(n³) 时间复杂度
- 四边形不等式优化后:O(n²) 时间复杂度
注意事项
- 需要先验证代价函数w是否满足四边形不等式
- 需要证明DP状态转移也满足四边形不等式
- 决策点单调性是优化的关键
四边形不等式优化是一种强大的技术,但应用时需要仔细验证前提条件是否满足。