菜雞的DP學習路程 斜率優化

2021-08-27 05:38:29 字數 1258 閱讀 4489

首先先看題。

這是一道顯而易見的dp題。

我們經過一番思考,就可以得出這道題的dp方程。

f[i][j]=min(0≤k我們著手於狀態優化。

狀態高維的原因顯然我們把機子重啟的時間記了下來。

我們用預支代價的方法,把狀態從2維降下來。

優化後的方程是

f[i]=min

這樣的話,這就是乙個n2的dp

過這道題是綽綽有餘了。

但是如果n<300000呢?

這個時候我們就可以用到斜率優化。

因為每次轉移的時候,我們都要列舉一遍j,這顯然很浪費時間。

有什麼方法可以讓我一下子就找到j在**呢??

我們把新的dp轉移方程展開,

按j整理一遍方程。

f[j]=f[i]-sumt[i]*sumc[i]+sumt[i]*sumc[j]-s*c[n]+s*sumc[j]

再次以j主元,得到下面的.

f[j]=(s+sumt[i])*sumc[j] + f[i]-sumt[i]*sumc[i]-s*c[n]

這就是乙個縱軸為f[j],橫軸為sumc[j]的一次函式。。。

斜率為(s+sumt[i])。

截距為f[i]-sumt[i]*sumc[i]-s*c[n]

為了讓f[i]取到最小值。顯然就要截距最小。,

截距最小的話。

然後就可以用單調佇列維護一下。

把上凹殼全部去掉。

下凹殼還是可以留著的。

上一下**

#include

#define min(a,b) ((a)>(b)?(b):(a))

const

int oo=1e9+7;

int sumt[300005],sumc[300005],s;

int f[300005];

int q[300005];

int main()

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

f[i]=oo;

int l=1,r=1;

q[1]=0;

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

printf("%d",f[n]);

}

學習筆記 斜率優化DP

作為數學渣,先複習一下已知兩點 x 1,y 1 x 2,y 2 怎麼求過兩點的一次函式的斜率.待定係數法代入 y kx b 有 x 1k b y 1 x 2k b y 2 兩式相減有 k frac 故事圍繞著 演算法競賽高階指南 的三一道例題展開 任務安排 1 假如我們啟動了乙個任務 l,r 那麼它...

斜率優化DP學習筆記

本文以luogup3195 玩具裝箱為例,我們很容易可以的出下面這個柿子 f i min 設 b i s i i j 為 f i 的最優決策點,則有 f i f j b i b j l 1 2 把只與 j 有關的放在左邊 f j b j 2 b j l 1 2 b i b j b i 2 l 1 2...

斜率優化DP 學習筆記 更新中

參考資料 1.元旦集訓的課件已經很好了 2.一 對於一類轉移方程 f i max a i 和c i 是開始求解前就知道常數,b j 和d j 知道f j 後就知道有關 可以使用斜率優化 不是這個形式就盡量往這個形式化 決策單調性 對於兩個轉移j和k,設b j 假設j比k優或相等,把式子一化就變成了 ...