四邊形不等式

2022-07-03 22:30:21 字數 4556 閱讀 2138

若有函式 \(a[i,j]\) ,令 \(i,若有:

\[a[i][j]+a[i+1][j+1]\le a[i][j+1]+a[i+1][j]

\]則我們稱函式 \(a\) 滿足四邊形不等式。

若我們在 \(dp\) 過程中會用到類似如下形式的方程:

\[dp[i][j]=min(dp[k][j]\ or\ dp[i][k]+dp[k+1][j])+w[i][j]

\]那麼,只要代價函式 \(w\) 滿足四邊形不等式,那麼函式 \(dp\) 一般也會滿足四邊形不等式。同時,假設 \(s[i][j]\) 為當 \(dp[i][j]\) 取得最優值的決策點,即:\(dp[i][j]=dp[s[i][j]]+w[i][j]\) ,一般 \(s\) 函式也會滿足四邊形不等式,這樣,通過移項我們會得到:

\[s[i+1][j]\le s[i][j]\le s[i][j-1]

\]或是:

\[s[i][j-1]\le s[i][j]\le s[i+1][j]

\]那麼我們選取決策點的轉移範圍就變小了,對於列舉決策點的複雜度為 \(o(n)\) 的轉移方程,它的列舉複雜度經過均攤,這個 \(o(n)\) 將會變成常數級別,常常能使 \(n^3\) 的 \(dp\) 降為 \(n^2\)。

給你環形排列的 \(n\) 堆石子 \((n\le 100)\) ,第 \(i\) 堆石子數量為 \(a_i\) ,每次選擇相鄰的兩堆合併,每次合併的代價將會是兩堆石子的數量之和,問將所有石子合併成一堆的最大與最小代價分別是多少。

不難想到,首先斷環為鏈,使之變成一條兩倍長度的鏈,然後做 \(n^3​\) 的區間的 \(dp​\) 。

設 \(w[i][j]​\) 為區間 \([i-j]​\) 的石子數量之和, \(fmin[i][j],fmax[i][j]​\) 為合併區間 \([i-j]​\) 的最小、最大代價,初始狀態為 \(fmin[i][i]=fmax[i][i]=0​\) :

列舉 合併的區間長度 len (2~n)

列舉 合併區間的左端點 i (1~n)

列舉 區間合併點 j (i~i+len-2)

這樣我們就得到了乙個 \(n^3​\) 的 \(dp​\) ,雖然對於題目來說確實夠用了,但是如果 \(n\le 1000​\) 呢?這時候我們應該考慮如何優化。

可以觀察到 \(fmin​\) 的轉移式滿足使用四邊形不等式的基本特徵,同時,\(w​\) 函式也滿足四邊形不等式。那麼,我們可以考慮使用四邊形不等式了:

利用決策點的單調性 \(s[i][j-1]\le s[i][j]\le s[i+1][j]​\) 來優化第三層迴圈即可,初始狀態為:\(s[i][i]=i​\) 。

列舉決策點轉移時同時更新 \(s[i][j]\) 來決策就好。

首先有這樣乙個結論:\(f[i][j]\) 的最優決策點必定在 \(i\) 與 \(j-1\) 兩者之間。

考慮如何證明,反證法奉上:

設 \(w[i][p]\) 與 \(w[p+1][j]\) 的差值函式為 \(s=w[i][p]-w[p+1][j]\) ,可以觀察到此函式單峰。

若最優決策點為 \(i< p< j-1\) ,我們設 \(s[p+1][j]=k\) ,那麼相應轉移方程為:

\[f[i][j]=f[i][p]+f[p+1][k]+f[k+1][j]+w[p+1][j]+w[i][j]

\]對應的,我們的合併方案為:

\[(a[i],a[i+1],...,a[p])u((a[p+1],a[p+2],...,a[k])u(a[k+1],a[k+2],...,a[j]))

\]那麼我們考慮另一種合併方式:

\[((a[i],a[i+1],...,a[p])u(a[p+1],a[p+2],...,a[k]))u(a[k+1],a[k+2],...,a[j])

\]則對應的轉移方程為:

\[f[i][j]=f[i][p]+f[p+1][k]+f[k+1][j]+w[i][p]+\sum_^ja[l] +w[i][j]

\]由於另一種合併方式必定比原決策更優,即選取決策點 \(k\) 優於 \(p\) ,\(k>p\) ,由於函式 \(s\) 在 \(>=0\) 右側區間單調遞增,則若選取決策點為 \(p\) 且 \(s>=0\) 且 \(p,那麼總有選取 \(k=s[p+1][j]>p\) 優於 \(p\) ,那麼由此可知對於某個決策點 \(q\) 往右的決策必定單調制優。則對於所有 \(p>q\) ,選取 \(p=j-1\) 將會最優。

類似的,設最優決策點為 \(i,我們設 \(s[i][p]=k\) ,那麼對應值為:

\[f[i][k]+f[k+1][p]+f[p+1][j]+w[i][p]+w[i][j]

\]同樣,我們考慮另一種合併方式:合併 \([i,k]([k+1,p][p+1,j])\) ,則此時的值為

\[f[i][k]+f[k+1][p]+f[p+1][j]+w[p+1][j]+w[i][j]+\sum_^pa[l]

\]則另一種必定優於原本的決策。

那麼對於上面的決策點 \(q\) 往左的決策必定單調制優,因為對於任意 \(p>i\) 且 \(s<0\) 都必定有決策點 \(k=s[i][p]要更優,則在左端點選取 \(p=i\) 最優。

得證,故轉移決策點僅需在 \(i\) 與 \(j-1\) 之間選取。

重點看 \(dp\) 就好 = =。

#include #include #include using namespace std;

int n, a[101], fmax[201][101], posi[201][101], fmin[201][101], maxans, minans;

int main()

for (int i = 1; i <= 2 * n; i++)

a[i] += a[i - 1], fmin[i][i] = 0, posi[i][i] = i; //初始化 dp 陣列與 決策點

for (int i = 1; i < n; i++)

for (int j = 1; j <= 2 * n - i; j++)

for (int i = 1; i <= n; i++)

cout << minans << endl;

cout << maxans;

}

一條直線上分布著 \(n\) 個村子 \((n\le 500)\) ,第 \(i\) 個村子距離第 \(i+1\) 個村子的距離為 \(a_i\) ,要求在 \(n\) 個村子中選取 \(m\) 個建造小學 \((m\le n)\) ,使得所有村子到距離它最近的小學的距離和最小。輸出最小距離和。

一道很經典的 \(dp\) 題。設 \(w[i][j]\) 為在村莊 \(i-j\) 中只建立乙個小學,所有村莊到這個小學的最小距離和。而這個最小距離和的位置必定為最中間的那個村莊,這也是乙個經典的數學證明,即中位數為最小距離和的位置。

設 \(f[i][j]\) 為對於前 \(i\) 個村莊建立 \(j\) 個小學的最小距離和,那麼轉移方程為:

\[f[i][j]=min(f[k][j-1]+w[k+1,i])

\]\(w\) 函式只需要勤記字首和即可轉移時 \(o(1)\) 求出。

不用疑惑為什麼這樣轉移沒有考慮第 \(k+1-i\) 個村莊中為什麼不會有到前 \(k\) 個村莊的小學距離更短的村莊,因為這樣反正不會影響答案使之變劣。

經過大眼 or 打表觀察法, 我們發現 \(w\) 函式又滿足四邊形不等式!那麼我們假設 \(s[i][j]\) 為 \(f[i][j]\) 的最優決策點,即 \(f[i][j]=f[s[i][j]][j-1]+w[s[i][j]+1][i]\) ,我們同樣可以猜想套路:

\[s[i-1][j]\le s[i][j]\le s[i+1][j]

\]那麼初始化為:

\(f[i][1]=w[1][i],s[i][1]=(i+1)>>1,s[n+1][i]=n\)

完畢。\(dp\) 才是重點,碼風比較仙。

#include #include #include using namespace std;

int n, m, d[501], q[501], h[502], f[501][501], pos[502][501], inf = 1e9;

int work(int l, int r) // w 函式計算

int main()

for (int l = 1; l <= 2; l++)

for (int i = 1; i <= n; i++) q[i] += q[i - 1]; //初始化字首和的字首和

for (int l = 1; l <= 2; l++)

for (int i = n; i >= 1; i--) h[i] += h[i + 1]; //初始化字尾和的字尾和

for (int i = 1; i <= n; i++)

f[i][1] = work(1, i), pos[i][1] = 0; //初始化 dp 陣列與決策點

for (int j = 2; j <= m; j++)

}} cout << f[n][m];

}

四邊形不等式是乙個套路,雖然不常見,但是應熟記於心以防萬一。

同時,考場上要通過數學證明函式滿足四邊形不等式其實還是蠻困難的,建議不要頭鐵,打打表證明就好了= = 。

四邊形不等式

總結一下最近幾天對dp優化中的四邊形不等式的學習。證明什麼的似懂非懂,我還是太年輕了。第一種,n 2 nlogn 例題 由於許可權問題 不公開題面 就是1個體積均為1 300,100000個物品,做乙個100000的揹包。發現體積最多只有 300 種,分開做。對於同種體積的物品,顯然按照價值從大到小...

四邊形不等式相關

四邊形不等式,即 w i j w i j w i j w i j 其中 i i j j 順便推薦兩篇 四邊形不等式 動態規劃演算法優化技巧 我是這麼總結的 1 狀態轉移方程形如 f i opt 其中b i j i 1 說明 b i 是根據題目描述的可以決策狀態i的左邊界,w j i 是狀態j轉移到狀...

DP 四邊形不等式

by qw 關於四邊形不等式或石子合併的資料。網上有很多。但有不少都是語焉不詳,直接拋給你幾個結論,讓人很難理解。這篇文章將以石子合併為例。證明關於四邊形不等式的一些結論。算是乙個溫習。題面 在乙個操場上擺放著一排n n 20 堆石子。現要將石子有次序地合併成一堆。規定每次只能選相鄰的2堆石子合併成...