看了那么久的四邊形不等式優化的原理,今天終於要寫一篇關於它的證明了。
在平時的做題中,我們會遇到這樣的區間dp問題
它的狀態轉移方程形式一般為dp[i][j]=min(dp[i][k]+dp[k+1][j]+cost[i][j]);(或者是max(........),本博客以min為例來證明)
熟悉一般區間dp的同學應該清楚我們如果想得到最終的答案,一般要用三層for循環來計算(第一層為長度,第二層枚舉起始點,第三層在起始點i和終點j之間尋找最優的分割點)。顯而易見它的時間復雜度為o(n^3),但是當cost滿足四邊形不等式的要求時我們就可以將他優化為o(n^2)。
為什么可以這樣呢,請慢慢往下看
首先什么是滿足四邊形不等式呢
滿足四邊形不等式用通俗話來講就是對於一個區間值關系,如果它滿足交叉小於包含的話,那么就說它是滿足四邊形不等式的。
例如當i < i' <= j < j'時,對於cost的值來說,如果它滿足 cost[i][j]+cost[i'][j']<=cost[i][j']+cost[i'][j] 的關系時,那么我們就說它滿足四邊形不等式。
我們如果想證明一個區間值關系是否滿足四邊形不等式,光依靠上面的式子來判斷還是有點困難的,我們不妨把上面的式子變動一下
我們以 i+1 來替換 i‘ ,以 j+1 來替換 j’ (即 i < i+1<= j < j+1 ),得到下面的式子
即當我們證明了 cost[i][j]+cost[i+1][j+1]<=cost[i][j+1]+cost[i+1][j] 時 ,我們就證明了它滿足四邊形不等式
我們把它移一下項
變成 cost[i][j]-cost[i+1][j]<=cost[i][j+1]-cost[i+1][j+1]
也就是證明函數F( j )=cost[i][j]-cost[i+1][j] 遞增(即F( j )<=F( j+1 ))
當我們的花費數組cost[i][j]滿足四邊形不等式時,我們怎么將dp的時間復雜度優化為o(n^2)呢?
不幸的是,我們還要證明dp[i][j]滿足四邊形不等式才行,但是dp數組是我們要求的,它不是已知的,我們怎么知道它滿不滿足呢。
還記得我們剛剛證明了cost滿足四邊形不等式了嗎,我們可以利用cost來推出dp滿足四邊形不等式
即證當 i< i+1<=j< j+1 時
dp[i][j]+dp[i+1][j+1]<=dp[i+1][j]+dp[i][j+1]
這個證明有點抽象,我先以一道題目為例使它更加容易理解
樣例
7
13 7 8 16 21 4 18
輸出
239
我們利用數學歸納法來證明dp數組滿足四邊形不等式(學過高等數學的同學應該不陌生)(如果你不知道什么是數學歸納法的話請點這里)
我們要證明dp[i][j] + dp[i+1][j+1] <= dp[i][j+1]+dp[i+1][j]成立(i < i+1 <= j < j+1)
1.當 i=1,j=2時(此時i+1=j)
因為
dp[1][1]=dp[2][2]=dp[3][3]=0,
dp[1][2]=w[1][2],dp[2][3]=w[2][3],
dp[1][3]>=w[1][3]
而由四邊形不等式可知
w[1][2]+w[2][3]<=w[1][3]+w[2][2]
顯然dp[1][2]+dp[2][3]<=dp[1][3]+dp[2][2]成立
2.我們令dp[i][j+1]取得最優值的時候k=x
令dp[i+1][j]取得最優值的時候k=y
當x < =y時(之后還要令x > y的情況類似)
我們假設dp[x+1][j] + dp[y+1][j+1] <= dp[x+1][j+1] + dp[y+1][j] 成立 (此時x+1 <= y+1 <= j < j+1)
這一步是數學歸納法中重要的一部分,先假設小范圍的成立,然后推出大范圍的成立
對於(i < i+1<=j<j+1)
顯然
dp[i][j] <= dp[i][x] + dp[x+1][j] + cost[i][j]
dp[i+1][j+1] <= dp[i+1][y] + dp[y+1][j+1] + cost[i+1][j+1]
dp[i][j] + dp[i+1][j+1]<=dp[i][x] + dp[x+1][j] + cost[i][j] + dp[i+1][y] + dp[y+1][j+1] + cost[i+1][j+1]
又因為cost滿足四邊形不等式
cost[i][j] + cost[i+1][j+1] <= cost[i][j+1] + cost[i+1][j]
所以dp[i][x] + dp[x+1][j] + cost[i][j] + dp[i+1][y] + dp[y+1][j+1] + cost[i+1][j+1]
<= dp[i][x] + dp[x+1][j] + cost[i][j+1] + dp[i+1][y] + dp[y+1][j+1] + cost[i+1][j]
又因為dp[x+1][j] + dp[y+1][j+1] <= dp[x+1][j+1] + dp[y+1][j] 成立
所以dp[i][x] + dp[x+1][j] + cost[i][j+1] + dp[i+1][y] + dp[y+1][j+1] + cost[i+1][j]
<= dp[i][x] + dp[x+1][j+1] + cost[i][j+1] + dp[i+1][y] + dp[y+1][j] + cost[i+1][j]
=dp[i][j+1]+dp[i+1][j]
即dp[i][j] + dp[i+1][j+1] <= dp[i][j+1]+dp[i+1][j] 成立
(x+1 <= y+1 <= j < j+1)是包含在(i < i+1 <= j < j+1)里的
綜上,由數學歸納法得證dp也滿足四邊形不等式
不理解的同學可以這樣想想,顯然dp[1][1],dp[2][2].....dp[n-1][n-1],dp[n][n]的值在本題中顯然為0,它是滿足四邊形不等式的(此時dp長度為1)
而dp[1][2],dp[2][3].....dp[n-2][n-1],dp[n-1][n]的值顯然為cost[1][2],cost[2][3].....cost[n-2][n-1],cost[n-1][n], 它是滿足四邊形不等式的(由dp[1][2]+dp[2][3]<=dp[1][3]+dp[2][2]成立可以類比推出來)
(此時dp的長度為n-(n-1)+1=2,即長度為2,枚舉每個起點,知道長度,得到他們的dp值)
對於dp長度為3的值,它一定是長度小於它的dp值推出來的,所以,當長度小於它的dp值滿足四邊形不等式時,我們可以推出當前長度為3的dp值也滿足四邊形不等式
一直只要依次推下去,就可以得到dp是滿足四邊形不等式的
現在我們推出了dp是滿足四邊形不等式的
我們現在就可以嘗試去降低算法的時間復雜度了
那它是怎么降低的呢?
我們只要證明最后一樣關系式就可以了
即s[i][j-1]<=s[i][j]<=s[i+1][j](s[i][j]表示dp[i][j]的最優分割點(dp[i][j]=min(t|dp[i][t]+dp[t+1][j]+cost[i][j])))
我們令d=s[i][j-1] , k <= d
cut=x 表示以x為分割點的dp值(即dp[i][j]=dp[i][x]+dp[x+1][j]+cost[i][j])
構造一個式子
(dp[i][j] - dp[i][j]) - (dp[i][j-1] - dp[i][j-1])
cut=k cut=d cut=k cut=d
=(dp[i][j] + dp[i][j-1]) - (dp[i][j-1] + dp[i][j])
cut=k cut=d cut=k cut=d
=(dp[i][k]+dp[k+1][j]+cost[i][j]+dp[i][d]+dp[d+1][j-1]+cost[i][j-1])-(dp[i][k]+dp[k+1][j-1]+cost[i][j-1]+dp[i][d]+dp[d+1][j]+cost[i][j] )
=(dp[k+1][j]+dp[d+1][j-1])-(dp[k+1][j-1]+dp[d+1][j])
因為 k+1<=d+1 <=j-1< j,由四邊形不等式可知
=dp[k+1][j]+dp[d+1][j-1] >= dp[k+1][j-1]+dp[d+1][j]
所以
(dp[i][j] - dp[i][j]) - (dp[i][j-1] - dp[i][j-1]) >= 0
cut=k cut=d cut=k cut=d
移一下項
(dp[i][j] - dp[i][j]) >= (dp[i][j-1] - dp[i][j-1])
cut=k cut=d cut=k cut=d
又因為d是dp[i][j-1]的最優分割點
所以
(dp[i][j-1] - dp[i][j-1]) >=0 (因為cut=d時dp[i][j-1]取最小值,cut取其他位置時得到的值必然大於在d點切割取的值)
cut=k cut=d
所以
(dp[i][j] - dp[i][j]) >=0
cut=k cut=d
又因為k是任意小於d的數(k<=d)
dp[i][j] >= dp[i][j]
cut=k cut=d
所以要想dp[i][j]最小,那么它的最優分割點s[i][j]必然大於等於d (d=s[i][j-1])
即 s[i][j] >= s[i][j-1]
證畢,同理可得
s[i][j] <= s[i+1][j]
有了s[i][j-1]<=s[i][j]<=s[i+1][j]這個結論
我們就可以把第三層for循環找最優分割點的區間從(i,j) 縮小到(s[i][j-1],s[i+1][j])
這樣就把第三層for循環的時間復雜度從o(n)降到o(1)
從而把整個時間復雜度從o(n^3)降到o(n^2)。
本人因為知識有限,本博客的證明可能存在不正確的地方,歡迎大家加我的QQ給予指教。
qq:2465806616
參考博客:
https://blog.csdn.net/qq_41695941/article/details/83025188
https://blog.csdn.net/noiau/article/details/72514812