POJ 動態規劃 3

2021-09-06 07:29:39 字數 1628 閱讀 9419

動態規劃

需要用資料結構優化的動態規劃

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 #include 

#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 3378

詳見:

四邊形不等式理論、斜率優化

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...