題解 P1622 釋放囚犯
題面
題目描述
Caima 王國中有一個奇怪的監獄,這個監獄一共有 個牢房,這些牢房一字排開,第 個緊挨著第 個(最後一個除外)。現在正好牢房是滿的。
上級下發了一個釋放名單,要求每天釋放名單上的一個人。這可把看守們嚇得不輕,因為看守們知道,現在牢房中的 個人,可以相互之間傳話。如果某個人離開了,那麼原來和這個人能說上話的人,都會很氣憤,導致他們那天會一直大吼大叫,搞得看守很頭疼。如果給這些要發火的人吃上肉,他們就會安靜點。
輸入格式
第一行兩個整數 和 , 表示釋放名單上的人數;
第二行 個整數,表示要釋放哪些人,保證按遞增的順序給出。
輸出格式
僅一行,表示最少要給多少人次送肉吃。
樣例 #1
樣例輸入 #1
1 | 20 3 |
樣例輸出 #1
1 | 35 |
提示
樣例說明 #1
先釋放 號監獄中的罪犯,要給 到 號監獄和 到 號監獄中的 人送肉吃;再釋放 號監獄中的罪犯,要給 到 號監獄和 到 號監獄中的 人送肉吃;最後釋放 號監獄中的罪犯,要給 到 號監獄和 到 號監獄中的 人送肉吃。
資料規模與約定
- 對於 的資料,,;
- 對於 的資料,,,,保證釋放的人所在的牢房編號按遞增的順序給出。
思路
題意即求釋放列表中所有罪犯的費用之和最小,每次釋放,罪犯i到他兩邊空牢房之間的所有人,都需要消耗一塊肉。每次釋放一個罪犯,可以想到區間 DP,狀態 f[l][r] 表示從l到r號罪犯全部釋放所需要消耗的肉塊總數。
之後思考狀態轉移方程。要求最小值,f[l][r] 初始值 INT_MAX。f[l][r] = min of f[l][m-1] + f[m+1][r] + Pos[r+1] - Pos[l-1] -2 ,其中 m 屬於區間 [l,r],列舉合併點,即此次釋放的罪犯,罪犯兩側到l和r號罪犯的消耗f[l][m-1]和f[m+1][r]。Pos[i]定義i號罪犯的編號。這裡其實是一種反向的思路,m點應該是最先釋放的(?Pos[r+1] - Pos[l-1] -2即此區間兩側最近的罪犯之間的人數,減去區間兩端。即區間合併的額外費用。注意要在Pos陣列中定義Pos[Q+1]=N+1。
程式碼
1 |
|
小結
本題難點在於建模,區間DP部分比較典型。