動態規劃
需要用資料結構優化的動態規劃
poj2754,poj3378,poj3017
四邊形不等式理論、斜率優化
poj1160,poj1180,poj3709
較難的狀態dp、插頭dp
poj3133,poj1739,poj2411、poj1763
需要用資料結構優化的動態規劃
poj 3017
題意:給乙個長為n的序列a,從中可以畫出k個子序列,s1,s2,... ,sk。求這些子串行中sigma(max(s[i]))最小。(1<=i<=k)並且滿足sigma(s[i])<= m;
解:轉移方程,f[i] = min(f[j] + max(num[j+1...i])),這是乙個很樸素的o(n^2)的複雜度。需要優化。
可以發現,對於f, 如果j < i那麼f[j] <= f[i]。所以f[i]是單調的,要取最小首先考慮j足夠小的問題,但是num[j+1...i]這一段就沒有大小序列了。怎麼辦,直接開單調佇列,儲存乙個從大到小的佇列。計算結果的時候直接從隊頭取元素轉移,即:f[i] = f[q[head]-1] + num[q[head]](這裡佇列記錄的是數的下標)。這還不一定能滿足所有的情況
比如序列4 5 3, m = 9
f[1] = 4, f[2] = 5, f[3] = 8;
但如果單純的f[i] = f[q[head]-1] + num[q[head]],f[3] = f[1] + num[2] = 9;
其實f[i]的最優解在f[i] = min(f[q[i-1]] + num[q[i]]);即根據單調佇列裡面相鄰的兩個元素進行轉移。
#include #includepoj 3378#include
#include
using
namespace
std;
typedef
long
long
ll;const
int n = 100020
;ll num[n];
ll sum[n];
ll f[n];
intq[n];
intmain()
while(st <= ed && num[i] >= num[q[ed]]) --ed;
q[++ed] =i;
while(sum[i] - sum[p-1] > m) ++p;
while(st <= ed && p > q[st]) st++;
if(st > ed) continue
;
if(f[p-1] != -1
) f[i] = f[p-1] +num[q[st]];
for(j = st + 1; j <= ed; ++j)
}printf(
"%i64d\n
",f[n]);
}return0;
}
詳見:
四邊形不等式理論、斜率優化
poj 1160
詳見:
poj 1180 && poj 3709
poj 動態規劃 1141
dp練習的第三道題,依然花了我斷斷續續好幾個小時 有人說看到題目裡的 2.if s is a regular sequence,then s and s are both regular sequences.3.if a and b are regular sequences,then ab is ...
動態規劃 硬幣 POJ
總時間限制 1000ms 記憶體限制 262144kb 描述 太空人bob有一天來到火星上,他有收集硬幣的習慣。於是他將火星上所有面值的硬幣都收集起來了,一共有n種,每種只有乙個 面值分別為a1,a2 an。bob在機場看到了乙個特別喜歡的禮物,想買來送給朋友alice,這個禮物的 是x元。bob很...
動態規劃(3)
robberies include include include includeusing namespace std 這題是參考的 自己的能力還是不可以。不過做了這題,再和0 1揹包問題想一想,覺得收穫還是不錯。說將逃跑率當成物品價值 小弟還是要繼續消化這條題的思想。double f 10020...