区间DP四边形不等式优化

2020-11-13
5分钟阅读时长

石子合并

先看一道最经典的区间DP题洛谷P1880 石子合并

题意

有一个圆形的操场,放着N堆石子,我们只能将相邻的两堆石子合并成一堆,花费是两堆石子数的和,问将N堆合并成一堆的最大最小花费是多少。

思路

以最大值为例,我们定义dpi,jdp_{i, j}表示将第ii和第jj堆石子合并的最大花费,我们从小区间开始枚举,通过状态转移方程求的大区间的最优解。对于求dpi,jdp_{i, j}时,我们枚举k(ik<j)k \quad (i \le k < j),找到最大的dpi,k+dpk+1,j+cost(i,j)dp_{i, k} + dp_{k + 1, j} + cost(i, j)即可。

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> P;
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3f
#define IO ios::sync_with_stdio(0)
#define DEBUG(x) cout<<"--->"<<(x)<<endl;
const ll mod = 998244353;
const double eps = 1e-9;
const double PI = acos(-1);
const int maxn = 1e4 + 5;

int a[205], pre[205];
int dp1[205][205], dp2[205][205];	// 最大,最小

int main() {
	// freopen("in.txt", "r", stdin);
	int n;
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
		a[i + n] = a[i];
	}
	for (int i = 1; i <= (n<<1); i++) {
		pre[i] = pre[i - 1] + a[i];
	}
        // 从小到大枚举长度
	for (int len = 2; len <= n; len++) {
		for (int i = 1, j = len; j <= (n<<1); i++, j++) {
			dp2[i][j] = inf;
                        // 枚举中间最优点k
			for (int k = i; k < j; k++) {
				dp1[i][j] = max(dp1[i][j], dp1[i][k] + dp1[k + 1][j] + pre[j] - pre[i - 1]);
				dp2[i][j] = min(dp2[i][j], dp2[i][k] + dp2[k + 1][j] + pre[j] - pre[i - 1]);
			}
		}
	}
	int mx = 0, mi = inf;
	for (int i = 1, j = n; j <= (n<<1); i++, j++) {
		mx = max(mx, dp1[i][j]);
		mi = min(mi, dp2[i][j]);
	}
	cout << mi << '\n' << mx << '\n';
	return 0;
}

四边形不等式优化

很显然上面的做法的时间复杂度为O(n3)O(n^3)的,对于大数据肯定是会很慢的,如果满足某些条件,可以将类似的DP优化成O(n2)O(n^2),大大降低复杂度。

对于上面的状态转移方程可以写成这样的形式 dp(l,r)=minlkr1{dp(l,k)+dp(k+1,r)}+w(l,r)(1lrn) dp(l, r) = min_{l \le k \le r - 1} \lbrace dp(l, k) + dp(k + 1, r) \rbrace + w(l, r) \quad (1 \le l \le r \le n)

区间包含单调性

对于任意的llrrl \le l’ \le r’ \le r,均有w(l,r)w(l,r)w(l’, r’) \le w(l, r)成立,则称函数ww对于区间包含关系具有单调性。

四边形不等式

如果对于任意的l1l2r1r2l_1 \le l_2 \le r_1 \le r_2,均有w(l1,r1)+w(l2,r2)w(l1,r2)+w(l2,r1)w(l_1, r_1) + w(l_2, r_2) \le w(l_1, r_2) + w(l_2, r_1)成立,则称函数ww满足四边形不等式,也叫做交叉小于包含。

引理1

若关于区间包含的单调性函数w(l,r)w(l, r)满足四边形不等式,则状态dp(l,r)dp(l, r)也满足四边形不等式。

定义sk,l,r=dpl,k+dpk+1,r+w(l,r)s_{k, l, r} = dp_{l, k} + dp_{k + 1, r} + w(l, r)表示当决策为kk时的状态值,任取l1l2r1r2l_1 \le l_2 \le r_1 \le r_2,记u=Bestl1k<r2sk,l1,r2u = \mathop{Best}\limits_{l_1 \le k < r_2}s_{k, l_1, r_2}v=Bestl2k<r1sk,l2,r1v = \mathop{Best}\limits_{l_2 \le k < r_1}s_{k, l_2, r_1}分别表示状态dpl1,r2dp_{l_1, r_2}dpl2,r1dp_{l_2, r_1}的最优抉择点。

  • uvu \le v,则l1u<r1,l2v<r2l_1 \le u < r_1, l_2 \le v < r_2,因此 dpl1,r1su,l1,r1=dpl1.u+dpu+1,r1+w(l1,r1)(1)dpl2,r2sv,l2,r2=dpl2,v+dpv+1,r2+w(l2,r2)(2) dp_{l_1, r_1} \le s_{u, l_1, r_1} = dp_{l_1. u} + dp_{u + 1, r_1} + w(l_1, r_1) \quad (1) \\ dp_{l_2, r_2} \le s_{v, l_2, r_2} = dp_{l_2, v} + dp_{v + 1, r_2} + w(l_2, r_2) \quad (2) 再由u+1v+1r1r2u + 1 \le v + 1 \le r_1 \le r_2和归纳假设知 dpu+1,r1+dpv+1,r2dpu+1,r2+dpv+1,r1(3) dp_{u + 1, r_1} + dp_{v + 1, r_2} \le dp_{u + 1, r_2} + dp_{v + 1, r_1} \quad (3) (1)(1)(2)(2)相加,得 dpl1,r1+dpl2,r2dpl1,u+dpl2,v+dpu+1,r1+dpv+1,r2+w(l1,r1)+w(l2,r2)(4) dp_{l_1, r_1} + dp_{l_2, r_2} \le dp_{l_1, u} + dp_{l_2, v} + dp_{u + 1, r_1} + dp_{v + 1, r_2} + w(l_1, r_1) + w(l_2, r_2) \quad (4) (3)(3)代入(4)(4)中,并且根据ww函数满足四边形不等式,得 dpl1,r1+dpl2,r2dpl1,u+dpl2,v+dpu+1,r2+dpv+1,r1+w(l1,r2)+w(l2,r1)su,l1,r2+sv,l2,r1=dpl1,r2+dpl2,r1 \begin{aligned} dp_{l_1, r_1} + dp_{l_2, r_2} \le& dp_{l_1, u} + dp_{l_2, v} + dp_{u + 1, r_2} + dp_{v + 1, r_1} + w(l_1, r_2) + w(l_2, r_1) \\ \le& s_{u, l_1, r_2} + s_{v, l_2, r_1} = dp_{l_1, r_2} + dp_{l_2, r_1} \end{aligned}

  • u>vu > v,则l1vr1l_1 \le v \le r_1l2ur2l_2 \le u \le r_2,因此 dpl1,r1sv,l1,r1=dpl1,v+dpv+1,r1+w(l1,r1)(5)dpl2,r2su,l2,r2=dpl2,u+dpu+1,r2+w(l2,r2)(6) dp_{l_1, r_1} \le s_{v, l_1, r_1} = dp_{l_1, v} + dp_{v + 1, r_1} + w(l_1, r_1) \quad (5) \\ dp_{l_2, r_2} \le s_{u, l_2, r_2} = dp_{l_2, u} + dp_{u + 1, r_2} + w(l_2, r_2) \quad (6) 再由l1l2vul_1 \le l_2 \le v \le u和归纳假设知 dpl1,v+dpl2,udpl1,u+dpl2,v(7) dp_{l_1, v} + dp_{l_2, u} \le dp_{l_1, u} + dp_{l_2, v} \quad (7) (5)(5)(6)(6)相加,得 dpl1,r1+dpl2,r2dpl1,v+dpl2,u+dpv+1,r1+dpu+1,r2+w(l1,r1)+w(l2,r2)(8) dp_{l_1, r_1} + dp_{l_2, r_2} \le dp_{l_1, v} + dp_{l_2, u} + dp_{v + 1, r_1} + dp_{u + 1, r_2} + w(l_1, r_1) + w(l_2, r_2) \quad (8) (7)(7)代入(8)(8)中,并且根据ww函数满足四边形不等式,得 dpl1,r1+dpl2,r2dpl1,u+dpl2,v+dpv+1,r1+dpu+1,r2+w(l1,r2)+w(l2,r1)su,l1,r2+sv,l2,r1=dpl1,r2+dpl2,r1 \begin{aligned} dp_{l_1, r_1} + dp_{l_2, r_2} \le& dp_{l_1, u} + dp_{l_2, v} + dp_{v + 1, r_1} + dp_{u + 1, r_2} + w(l_1, r_2) + w(l_2, r_1) \\ \le& s_{u, l_1, r_2} + s_{v, l_2, r_1} = dp_{l_1, r_2} + dp_{l_2, r_1} \end{aligned}

综上所述,两种情况都有dpl1,r1+dpl2,r2dpl1,r2+dpl2,r1dp_{l_1, r_1} + dp_{l_2, r_2} \le dp_{l_1, r_2} + dp_{l_2, r_1},则四边形不等式成立

决策单调性

定理1 :若状态dpdp满足四边形不等式,定义ml,r=min{k:dpl,r=sk,l,r}m_{l, r} = \min\lbrace k : dp_{l, r} = s_{k, l, r} \rbrace表示最优决策点,则有 ml,r1ml,rml+1,r m_{l, r - 1} \le m_{l, r} \le m_{l + 1, r} u=ml,ru = m_{l, r}k1=ml,r1k_1 = m{l, r - 1}k2=ml+1,rk_2 = m_{l + 1, r}

  • k1>uk_1 > u,则u+1k1+1r1ru + 1 \le k_1 + 1 \le r - 1 \le r,因此根据四边形不等式有 dpu+1,r1+dpk1+1,rdpu+1,r+dpk1+1,r1(9) dp_{u + 1, r - 1} + dp_{k_1 + 1, r} \le dp_{u + 1, r} + dp_{k_1 + 1, r - 1} \quad (9) ​根据uu是状态dpl,rdp_{l, r}的最优决策点可知 dpl,u+dpu+1,rdpl,k1+dpk1+1,r(10) dp_{l, u} + dp_{u + 1, r} \le dp_{l, k_1} + dp_{k_1 + 1, r} \quad (10) ​将(9)(9)(10)(10)两个不等式相加,得 dpl,u+dpu+1,r1dpl,k1+dpk1+1,r1su,l,r1sk1,l,r1 \begin{aligned} dp_{l, u} + dp_{u + 1, r - 1} \le& dp_{l, k_1} + dp_{k_1 + 1, r - 1} \\ s_{u, l, r - 1} \le& s_{k_1, l, r - 1} \end{aligned} 这与k1k_1是最小的最优决策点矛盾,所以k1uk_1 \le u

  • u>k2u > k_2,则ll+1+k2ul \le l + 1 \le + k_2 \le u,根据四边形不等式得 dpl,k2+dpl+1,udpl,u+dpl+1,k2(11) dp_{l, k_2} + dp_{l + 1, u} \le dp_{l, u} + dp_{l + 1, k_2} \quad (11) 根据k2k_2是状态dpl+1,rdp_{l + 1, r}的最优决策点可知 dpl+1,k2+dpk2+1,rdpl+1,u+dpu+1,r(12) dp_{l + 1, k_2} + dp_{k_2 + 1, r} \le dp_{l + 1, u} + dp_{u + 1, r} \quad (12) (11)(11)(12)(12)相加,得 dpl,k2+dpk2+1,rdpl,u+dpu+1,rsk2,l,rsu,l,r \begin{aligned} dp_{l, k_2} + dp_{k_2 + 1, r} \le& dp_{l, u} + dp_{u + 1, r} \\ s_{k_2, l, r} \le& s_{u, l, r} \end{aligned} 这与uu是最小的最优决策点矛盾,因此uk2u \le k_2

所以,如果我们在计算状态dpl,rdp_{l, r}的同时将最小的最优决策点ml,rm_{l, r}记录下来,那么我们队决策点kk的总枚举次数将为 1l<rnml+1,rml,r1=i=1nmi,nm1,in2 \sum\limits_{1 \le l < r \le n} m_{l + 1, r} - m_{l, r - 1} = \sum\limits_{i = 1}^{n} m_{i, n} - m_{1, i} \le n^{2}

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

因为求最大值时,不满足四边形不等式,只能优化求最小值,并且我们在求解dpl,rdp_{l, r}时,是需要知道ml,r1m_{l, r - 1}ml+1,rm_{l + 1, r}的,所以ll需要从大到小枚举,rr需要从小到大枚举

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> P;
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3f
#define IO ios::sync_with_stdio(0)
#define DEBUG(x) cout<<"--->"<<(x)<<endl;
const ll mod = 998244353;
const double eps = 1e-9;
const double PI = acos(-1);
const int maxn = 1e4 + 5;

int a[205], pre[205];
int dp1[205][205], dp2[205][205], m[205][205];

int main() {
	// freopen("in.txt", "r", stdin);
	int n;
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
		a[i + n] = a[i];
	}
	for (int i = 1; i <= (n<<1); i++) {
		pre[i] = pre[i - 1] + a[i];
		m[i][i] = i;
	}
	for (int i = (n<<1); i >= 1; i--) {
		for (int j = i + 1; j <= (n<<1); j++) {
			dp2[i][j] = inf;
			dp1[i][j] = max(dp1[i + 1][j], dp1[i][j - 1]) + pre[j] - pre[i - 1];
			for (int k = m[i][j - 1]; k <= m[i + 1][j]; k++) {
				if (dp2[i][j] > dp2[i][k] + dp2[k + 1][j] + pre[j] - pre[i - 1]) {
					dp2[i][j] = dp2[i][k] + dp2[k + 1][j] + pre[j] - pre[i - 1];
					m[i][j] = k;
				}
			}
		}
	}
	int mi = inf, mx = 0;
	for (int i = 1, j = n; j <= (n<<1); i++, j++) {
		mi = min(mi, dp2[i][j]);
		mx = max(mx, dp1[i][j]);
	}
	cout << mi << '\n' << mx << '\n';
	return 0;
}

参考

OI-Wiki 四边形不等式优化

B站 bewildRan - 0225【四边形不等式优化DP】

上一页 重链剖分
下一页 Treap
Powered By Valine
v1.4.16