若有函式 \(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堆石子合併成...