四邊形不等式優化 dp 學習筆記
N 總髮現並證明的不等式就是巧妙。
前置芝士:四邊形不等式
定義
設 \(W(x,y)\) 是定義在整數集合上的二元函式。若對於定義域上的任意整數 \(a,b,c,d\),其中 \(a \leq b \leq c \leq d\),都有 \(W(a,d)+W(b,c) \geq W(a,c)+W(b,d)\) 成立(對於四個整數的大小關係,可以簡單記憶為“交叉小於包含”),則稱函式 \(W\) 滿足四邊形不等式。
定理(四邊形不等式的另一種定義)
設 \(W(x,y)\) 是定義在整數集合上的二元函式。若對於定義域上的任意整數 \(a,b\),其中 \(a<b\),都有 \(W(a,b+1)+W(a+1,b) \geq W(a,b)+W(a+1,b+1)\)
從上往下推很簡單,只需要用 \(a+1\) 和 \(b+1\) 替換上面的 \(b\) 和 \(d\),將 \(b\) 改成 \(c\),就是上面的式子。下面簡單證明一下如何由下往上推:
對於 \(a<c\),有 \(W(a,c+1)+W(a+1,c) \geq W(a,c)+W(a+1,c+1)\)。
對於 \(a+1<c\),有 \(W(a+1,c+1)+W(a+2,c) \geq W(a+1,c)+W(a+2,c+1)\)。
兩式相加,得到 \(W(a,c+1)+W(a+2,c) \geq W(a,c)+W(a+2,c+1)\)
以此類推,對於任意的 \(a \leq b \leq c < c+1\),有 \(W(a,c+1)+W(b,c) \geq W(a,c)+W(b,c+1)\)。
同理,令 \(c=c+1\),對於 \(a \leq b \leq c+1 < c+2\),列出不等式,與上式相加,得到 \(W(a,c+2)+W(b,c) \geq W(a,c)+W(b,c+2)\)。
以此類推,對於 \(a \leq b \leq c \leq d\),都有 \(W(a,d)+W(b,c) \geq W(a,c)+W(b,d)\)。
得證。
故兩個式子等價。
一維線性 DP 的四邊形不等式優化
對於形如 $f[i]=\min_{0 \leq j < i}{(f[j]+val(j,i))} $ 的狀態轉移方程,記 \(p[i]\)
定理(決策單調性)
若 \(p\) 對於 \(i\),\(\forall j \in [0,p-1]\),都有決策 \(p\) 比 \(j\) 更優(決策 \(p\) 不一定為最優決策,即任意決策都具有單調性)。若函式 \(val\) 滿足四邊形不等式,則對於 \(\forall i'>i\),都有決策 \(p\) 比 \(j\) 更優。
證明:
由上面的關係可以得到 \(0 \leq j <p <i <i'\)。
根據 \(p\) 比決策 \(j\) 更優,可以得到不等式:
\(f[p]+val(p,i) \leq f[j]+val(j,i)\)--------①。
又 \(\because\) 函式 \(val\) 滿足四邊形不等式,得:
\(val(j,i')+val(p,i) \geq val(j,i)+val(p,i')\)。
移項,得:
\(val(p,i')-val(p,i) \leq val(j,i')-val(j,i)\)-----②。
① \(+\) ②,得:
\(f[p]+val(p,i') \leq f[j]+val(j,i')\)。
顯然,不等式的左右兩邊都是 \(f[i']\) 的一個決策點。故決策 \(p\) 比 \(j\) 更優。換言之,\(f[i']\) 的最優決策不可能小於 \(p\)。特別的,當 \(p\) 為 \(i\) 的最優決策,即 \(p[i]\) 時,可以得到 \(p[i'] \geq p[i]\)。所以 \(f\) 具有決策單調性。
得證。
當 \(f\) 有決策單調性時,就可以把形如 \(f[i]=\min_{0 \leq j < i}{(f[j]+val(j,i))}\) 的計算時間從 \(O(N^2)\) 優化到 \(O(N \log N)\)。
由上面的定理可以得到 \(\forall i'>i,p[i'] \geq p[i]\)。也就是 \(P\) 非嚴格單調遞增。
初始時,\(P\) 中全部為 \(0\)。在 \(i\) 迴圈的任意時刻,如果已經求出了 \(p[i]\),那麼就可以直接令 \(f[i]=p[i]+val(i,j)\)。而求出了 \(f[i]\) 之後, \(i\) 也就有可能去更新其他狀態。於是就用 \(i\) 來更新 \(p\) 陣列。
若 \(p\) 中某一位置取到 \(i\) ,那麼後面的所有位置都為 \(i\),因為當前最大的值就是 \(i\),而 \(p\) 陣列又滿足非嚴格單調遞增,後面的值都要 \(\geq i\),那麼後面的值就自然都為 \(i\) 了。
而要快速找到第一個取 \(i\) 的點的下標,顯然可以用二分查詢。
而一個個修改顯然效率太低了。因為 \(p\) 陣列滿足非嚴格單調遞增,所以可能存在一段很長的子區間,在這個子區間內 \(p\) 的值都相同(通過上面的修改操作也可以發現)。那麼就可以建立一個佇列來代替 \(p\) 陣列。佇列中保持若干個三元組 \((l,r,j)\),表示 \(p\) 在 \([l,r]\) 內的取值都為 \(j\)。
對於修改操作,就可以從隊尾開始查詢,如果發現當前區間的開頭填 \(i\) 更優,那麼直接刪去就可以;如果發現當前區間的開頭不應該填 \(i\),那麼判斷區間的結尾是否應該填 \(i\),如果結尾填 \(i\) 更優,那麼就說明這個區間可以分為兩部分,前面的部分保持不變,後面的部分改為 \(i\) 即可。而找到這個區間的分界點就可以用二分查詢。
可以發現,每個區間最多被刪除一次,刪除只需 \(O(1)\),每次查詢的時間下界為 \(O(\log N)\)。所以每一次修改的瓶頸就是 \(O(\log N)\),
而一旦求完 \(i\),由於 \(i\) 之後的決策點一定 \(\geq p[i]\),那麼佇列中所有小於 \(p[i]\) 的區間就沒有用了,直接刪除即可。那麼把所有不會用到的 \(p\) 刪去以後,佇列的開頭就是當前節點的最優決策點了(類似於單調佇列)。後面會給出具體程式碼。
例題 [NOI2009] 詩人小G
題意
給出若干個句子,將這些句子按順序排成若干行,給出一個期望長度 \(L\) 和一個整數 \(P\),設第 \(i\) 行句子(包括標點)的總長度為 \(x\),那麼第 \(i\) 行的不和諧度就為 \(|x-L|^P\)。求一個方案使得句子的總不和諧度最小,並輸出這個方案。
思路
設 \(f[i]\) 表示對前 \(i\) 句詩排版的最小不和諧度,記 \(a[i]\) 為第 \(i\) 句詩的長度,\(sum[i]\) 為前 \(i\) 句詩的總長度。得:
\(f[i]=\min_{0 \leq j < i}(f[j]+|(sum[i]-sum[j])+(i-j-1)-L|^P)\)。
可以發現,題目中的 \(P\) 就是用來防止單調佇列優化或斜率優化的。於是可以令 \(val(i,j)=(f[j]+|(sum[i]-sum[j])+(i-j-1)-L|^P)\)。嘗試判斷 \(val\) 是否滿足四邊形不等式。
也就是要證明:
\(\forall j<i\),滿足 \(val(j,i+1)+val(j+1,i) \geq val(j,i)+val(j+1,i+1)\)。
只需證明: \(val(j+1,i)-val(j+1,i+1) \geq val(j,i)-val(j,i+1)\)。
令 \(u=(sum[i]-sum[j])+(i-j-1)-L\)。
令 \(v=(sum[i]-sum[j+1])+(i-(j+1)-1)-L\)。
只需證明 \(|v|^p-|v+(a[i+1]+1)|^p \geq |u|^p-|u+(a[i+1]+1)|\)。
顯然 \(u>v\)。故只需證明,對於任意正整數 \(c\),函式 \(y=|x|^p-|x+c|^p\) 非嚴格單調遞減。接下來對於 \(p \in [1.10]\) 的奇偶性和 \(x\) 的範圍分類討論:
1.\(p\) 為偶數。\(y=x^p-(x+c)^p\)。對 \(x\) 求導,得 \(y'=px^{p-1}-p(x+c)^{p-1}\),顯然 \(x^{p-1}\) 單調遞增。而 \((x+c)^{p-1} \geq x^{p-1}\),\(p \geq 2\),故 \(y'\leq 0\)。
2.\(p\) 為奇數,且 \(x \in [-c,0]\) 時。\(y=-x^p-(x+c)^p\)。對 \(x\) 求導,得 \(y'=-p*x^{p-1}-p*(x+c)^{p-1}\)。因為 \(p-1\) 為偶數,\(p\) 是正整數,所以 \(y'\leq 0\)。
3.\(p\) 為奇數,且 \(x \in (-\infty,c)\) 時。\(y=-x^p+(x+c)^p,y'=-px^{p-1}+p(x+c)^{p-1}\)。而 \(|x| \geq |x+c|\),故 \(p*(x+c)^{p-1} \leq p*x^{p-1}\)。所以 \(y' \geq 0\)。
4.\(p\) 為奇數,且 \(x \in (0,\infty)\) 時。\(y=x^p-(x+c)^p,y'=px^{p-1}-p*(x+c)^{p-1}\)。因為 \(p-1\) 為奇數,故 \(x^{p-1}\) 在 \(x \in (0,\infty)\) 時單調遞增。故 \(p*x^{p-1} \leq p*(x+c)^{p-1}\)。故 $ y' \leq 0$。
故函式 \(y=|x|^p-|x+c|^p\) 非嚴格單調遞減。
因此,\(val\) 滿足四邊形不等式。上面的狀態轉移方程就可以用決策單調性優化。
最後需要注意一下本題中的資料範圍,最小的不和諧度也可能超過 \(10^{18}\),所以需要開 long double。
code:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define LD long double
const int N=1e5+10;
int T,n,l,p,s[N],opt[N],hh,tt;
struct node{
int l,r,j;
}q[N];
LD f[N];
char str[N][40];
LD val(int j,int i)
{
LD res=1,a=abs((s[i]-s[j])+(i-j-1)-l);
for(int i=1;i<=p;i++) res*=a;
return res+f[j];
}
void insert(int i)
{
int pos=n+1;
while(hh<=tt&& val(q[tt].j,q[tt].l)>=val(i,q[tt].l)) pos=q[tt--].l;
if(hh<=tt&&val(q[tt].j,q[tt].r)>=val(i,q[tt].r)) //如果當前區間的左端點是j更優,右端點是i更優
{
int l=q[tt].l,r=q[tt].r;
while(l<r)
{
int mid=(l+r)>>1;
if(val(q[tt].j,mid)>=val(i,mid)) r=mid;
else l=mid+1;
}
q[tt].r=r-1;//因為查詢的r是第一個i更優的,那麼j更優的就在r-1
pos=r;
}
if(pos!=n+1) q[++tt]=node{pos,n,i};
}
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d",&n,&l,&p);
for(int i=n;i>=1;i--) scanf("%s",str[i]);//便於輸出答案
for(int i=1;i<=n;i++) s[i]=s[i-1]+strlen(str[i]);
hh=0,tt=0;
q[0]=node{1,n,0};
for(int i=1;i<=n;i++)
{
f[i]=val(q[hh].j,i),opt[i]=q[hh].j;
if(q[hh].r==i) hh++;//如果當前這一段決策最多隻能作為i的最優決策點,那麼i以後的點也就不需要這段最優決策了
q[hh].l=i+1;//只需要關注後面沒賦值的點即可
insert(i);
}
if(f[n]>1e18) puts("Too hard to arrange");
else
{
printf("%lld\n",(long long)f[n]);
for(int i=n;i;i=opt[i])
{
for(int j=i;j>opt[i];j--)
{
printf("%s",str[j]);
if(j!=opt[i]+1) printf(" ");
}
puts("");
}
}
puts("--------------------");
}
return 0;
}
二維線性 DP 的四邊形不等式優化
定理
在狀態轉移方程 \(f[i][j]=\min_{i \leq k <j}(f[i][k]+f[k+1][j]+w(i,j))\) 中(特別地,\(f[i][i]=w(i,i)=0\)),如果下面兩個條件成立:
- \(w\) 滿足四邊形不等式。
2.對於任意的 \(a \leq b \leq c \leq d\),有 \(w(a,d) \geq w(b,c)\)。
那麼 \(f\) 也滿足四邊形不等式。
證明:
\(f[i][i+1]=f[i][i]+f[i+1][i+1]+w(i,i+1)=w(i,i+1)\)。(區間 \([i,i+1]\) 的決策點只能是 \(i\))
當 \(i+1=j\) 時,\(f[i][j+1]+f[i+1][j]=f[i][i+2]+f[i+1][i+1]=f[i][i+2]\)。
此時 \(f[i][i+2]\) 的最優決策點的取值只有 \(i\) 和 \(i+1\)。下面對取值進行分類討論:
若 \(f[i][i+2]\) 的最優決策是 \(i\),則 \(f[i][i+2]=f[i][i]+f[i+1][i+2]+w(i,i+2)=w(i,i+2)+w(i+1,i+2) \geq w(i,i+1)+w(i+1,i+2)=f[i][i+1]+f[i+1][i+2]=f[i][j]+f[i+1][j+1]\)。
若 \(f[i][i+2]\) 的最優決策是 \(i+1\),則 \(f[i][i+2]=f[i][i+1]+f[i+2][i+2]+w(i,i+2)=w(i,i+1)+w(i,i+2) \geq w(i,i+1)+w(i+1,i+2)=f[i][i+1]+f[i+1][i+2]=f[i][j]+f[i+1][j+1])\)。
而根據最上面的等式,就可以得到:
\(f[i][i+2]=f[i][i+2]+f[i+1][i+1]=f[i][j+1]+f[i+1][j] \geq f[i][j]+f[i+1][j+1]\)。
故當 \(i+1=j\) 時,四邊形不等式對 \(f[i][j]\) 成立。
接下來,用數學歸納法,假設當 \(j-i<k\) 時,四邊形不等式對 \(f(i,j)\) 成立。考慮 \(j-i=k\) 的情況。設 \(f[i][j+1]\) 以 \(x\) 為最優決策,\(f[i+1][j]\) 以 \(y\) 為最優決策。接下來對 \(x\) 和 \(y\) 的大小關係進行分類討論:
①.若 \(i \leq x \leq y <j\),同時也有 \(i \leq x \leq j,i+1\leq y < j\),
\(f[i][j+1]+f[i+1][j]=f[i][x]+f[x+1][j+1]+w(i,j+1)+f[i+1][y]+f[y+1][j]+w(i+1,j)\)。
同時 \(x\) 在 \(f[i][j]\) 的決策範圍內,\(y\) 在 \(f[i+1][j+1]\) 的決策範圍內,那麼 \(x,y\) 均可以作為一個決策(不一定是最優決策),就可以得到:
\(f[i][j]+f[i+1][j+1] \leq f[i][x]+f[x+1][j]+w(i,j)+f[i+1][y]+f[y+1][j+1]+w(i+1,j+1)\)
同時因為 \(w\) 滿足四邊形不等式,就可以得到:
\(i<i+1 \leq j < j+1\),\(w(i,j+1)+w(i+1,j) \geq w(i,j)+w(i+1,j+1)\)。
現在只需要證明:
\(f[i][x]+f[x+1][j+1]+f[i+1][y]+f[y+1][j] \geq f[i][x]+f[x+1][j]+f[i+1][y]+f[y+1][j+1]\)。
發現兩邊有相同項,可以消去,於是就只需證:
\(f[x+1][j+1]+f[y+1][j] \geq f[x+1][j]+f[y+1][j+1]\)。
根據歸納假設,\(x+1 \leq y+1 \leq j < j+1\),滿足 \(j-(x+1) <j-i=k\),那麼就可以得到:
\(f[x+1][j+1]+f[y+1][j] \geq f[x+1][j]+f[y+1][j+1]\)。
整理一下上面的式子,就可以得到:
\(f[i][j+1]+f[i+1][j]=f[i][x]+f[x+1][j+1]+w(i,j+1)+f[i+1][y]+f[y+1][j]+w(i+1,j) \geq f[i][x]+f[x+1][j]+w(i,j)+f[i+1][y]+f[y+1][j+1]+w(i+1,j+1) \geq f[i][j]+f[i+1][j+1]\)。
情況 ① 得證。
②.若 $i+1 \leq y \leq x \leq j $,就有 \(i+1 \leq x \leq j,i+1 \leq y <j\)。
根據 \(x\) 是 \(f[i][j+1]\) 的最優決策,\(y\) 是 \(f[i+1][j]\) 的最優決策,可以得:
\(f[i][j+1]+f[i+1][j]=f[i][x]+f[x+1][j+1]+w(i,j+1)+f[i+1][y]+f[y+1][j]+w(i+1,j)\)。
而 \(x\) 在 \(f[i+1][j+1]\) 的決策範圍內,\(y\) 在 \(f[i][j]\) 的決策範圍內,可以得:
\(f[i][j]+f[i+1][j+1] \leq f[i][y]+f[y+1][j]+w(i,j)+f[i+1][x]+f[x+1][y+1]+w(i+1,j+1)\)。
只需證明:
\(f[i][x]+f[x+1][j+1]+w(i,j+1)+f[i+1][y]+f[y+1][j]+w(i+1,j) \geq f[i][y]+f[y+1][j]+w(i,j)+f[i+1][x]+f[x+1][j+1]+w(i+1,j+1)\)。
因為 \(w\) 滿足四邊形不等式,得:
\(i<i+1 \leq j < j+1\),\(w(i,j+1)+w(i+1,j) \geq w(i,j)+w(i+1,j+1)\)。
消去不等式左右兩邊的 \(w\),以及相同項,只需證:
\(f[i][x]+f[i+1][y] \geq f[i][y]+f[y+1][j]\)。
根據情況假設,可以得到 \(y \leq x \leq j\)。
1.\(i < i+1 \leq y\leq x \leq j <\)。\(\because j-i =k\),\(\therefore x-(i+1) \leq k-1 < k\)。根據歸納假設,得:
$i <i+1 \leq y \leq x \(,\)f[i][x]+f[i+1][y] \geq f[i][y]+f[i+1][x]$。
整理式子,最終可得:
\(f[i][j+1]+f[i+1][j]=f[i][x]+f[x+1][j+1]+w(i,j+1)+f[i+1][y]+f[y+1][j]+w(i+1,j) \geq f[i][y]+f[y+1][j]+w(i,j)+f[i+1][x]+f[x+1][j+1]+w(i+1,j+1)=f[i][j]+f[i+1][j+1]\)。
得證。
定理:二維決策單調性
在狀態轉移方程\(f[i][j]=\min_{i \leq k <j}(f[i][k]+f[k+1][j]+w(i,j))\) 中(特別地,\(f[i][i]=w(i,i)=0\)),記 \(p[i][j]\) 為令 \(f[i][j]\) 取到最小值的 \(k\) 的值。
如果 \(f\) 滿足四邊形不等式,那麼對於任意 \(i<j\),有 \(p[i][j-1] \leq p[i][j] \leq p[i+1][j]\).
證明:
記 \(p=p[i][j]\),對於任意的 \(i<i+1 \leq k \leq p\),因為 \(F\) 滿足四邊形不等式:
\(f[i][p]+f[i+1][k] \leq f[i][k]+f[i+1][p]\)。
移項,得:
\(f[i+1][k]-f[i+1][p] \leq f[i][k]-f[i][p]\)。
根據 \(p\) 的最優性,得:
\(f[i][k]+f[k+1][j+1] \geq f[i][q]+f[q+1][j+1]\)。
在 \(f[i+1][j]\) 中任取 \(k \leq q\),讓兩個決策點相減,得:
\((f[i+1][k]+f[k+1][j]+w(i+1,j))-(f[i+1][q]+f[q+1][j]+w(i+1,j))\)
\(=(f[i+1][k]-f[i+1][q])+(f[k+1][j]-f[q+1][j])\)
\(\geq (f[i][k]-f[i][p])+(f[k+1][j]-f[q+1][j])\)
\(=(f[i][k]+f[k+1][j])-(f[i][p]+f[q+1][j])\)
\(\geq 0\)
那麼就意味著,對於 \(f[i+1][j]\),\(p\) 比之前的任意 \(k\) 更優。因此 \(p[i+1][j] \geq p[i][j]\)。同理可以證得 \(p[i][j-1] \leq p[i][j]\)。
得證。
例題 再探石子合併
題意
和簡化版的題意一樣,只不過本題中,\(n \leq 5000\)。
思路
首先令 \(s\) 表示石子個數的字首和,可以得到樸素的狀態轉移方程:
\(f[i][j]=\min_{i\leq k <j}(f[i][k]+f[k+1][j]+s[j]-s[i-1])\)。
如果用 \(w(i,j)\) 來替換 \(s[j]-s[i-1]\),那麼本題就完全是四邊形不等式優化的模板題了。
而在列舉 \(f[i][j]\) 時,區間長度 \(<(j-i+1)\) 的區間必然已經被搜過了,那麼這些區間的決策點也就必然知道,那麼根據上面證明的定理:
\(p[i][j-1] \leq p[i][j] \leq p[i+1][j]\)。
\(k\) 的範圍就可以控制在區間 \([p[i][j-1],p[i+1][j]]\) 中了。這樣的時間複雜就可以優化到 \(O(n^2)\)。
下面簡單證明一下時間複雜度:
對於區間 \([i,j]\),一共迴圈了 \(p[i+1][j]-p[i][j-1]+1\) 次,下圖統計了在 \(n=5\) 時,\(p[i][j]\) 的加減情況:
演算法的時間複雜度為 \(O( {\textstyle \sum_{i=1}^{N-1}}(p[l+1,N]-P[1,N-l]+N-l))=O(N^2)\)。
code:
#include<cstdio>
using namespace std;
const int N=5050;
const int INF=0x3f3f3f3f;
int f[N][N],s[N],n,p[N][N];
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&s[i]);
s[i]+=s[i-1];
p[i][i]=i;
}
for(int len=2;len<=n;len++)
for(int l=1;l<=n;l++)
{
int r=l+len-1;
f[l][r]=INF;
for(int k=p[l][r-1];k<=p[l+1][r];k++)
{
if(f[l][k]+f[k+1][r]+s[r]-s[l-1]<=f[l][r])
{
f[l][r]=f[l][k]+f[k+1][r]+s[r]-s[l-1];
p[l][r]=k;
}
}
}
printf("%d\n",f[1][n]);
return 0;
}
總結
事實上,如果在考試時遇到了狀態轉移方程很簡單,但時間複雜度不對的狀態轉移方程,如果這個狀態轉移方程即無法分離常數,也無法用斜率優化或其他優化。就可以考慮四邊形不等式優化。但不需要證明,因為太浪費時間了。可以先在樸素的轉移中記錄決策點,然後輸出,觀察決策點是否非嚴格單調遞增(一維和二維不同),如具有單調性就大概率可以用決策單調性優化(其實就是打表找規律)。