首先先看題。
這是一道顯而易見的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優或相等,把式子一化就變成了 ...