這裡淺顯(並且不嚴謹)地說明一下標題中的兩個名詞:
斜率優化dp:狀態轉移方程形如f[i]=min/max的一類dp問題;
決策單調性:若對於狀態i,有決策ti,存在決策k優於t。
對以上兩條說明的不嚴謹與模糊之處,下文將結合題目給出(依舊不嚴謹且模糊的)一定程度上的解釋。
pine開始了從s地到t地的征途。
從s地到t地的路可以劃分成n段,相鄰兩段路的分界點設有休息站。
pine計畫用m天到達t地。除第m天外,每一天晚上pine都必須在休息站過夜。所以,一段路必須在同一天中走完。
pine希望每一天走的路長度盡可能相近,所以他希望每一天走的路的長度的方差盡可能小。
幫助pine求出最小方差是多少。
設方差是v,可以證明,v×m^2是乙個整數。為了避免精度誤差,輸出結果時輸出v×m^2。
第一行兩個數 n、m。
第二行 n 個數,表示 n 段路的長度
乙個數,最小方差乘以 m^2 後的值
5 21 2 5 8 6
361≤n≤3000,保證從 s 到 t 的總路程不超過 30000
附上原題鏈結→_→problem 4518. -- [sdoi2016]征途
為方便書寫,作出如下約定:
a[i]:題目給出的第i段路程長;
sum[i]:路程長的字首和;
x[i]:第i天走過的路程總和。
根據題意,每天走過的路程長度的方差表示為:
顯然,由於上式中只有x[i]為變數,問題自然轉化成了求∑x2[i]的最小值。
設計狀態轉移方程如下:
其中,f[i][j]表示前j天走過前i段路程,每天路程平方和的最小值。
觀察到狀態轉移方程的形式基本符合斜率優化dp的形式,於是固定j,並:
令t當t優於k:
同理,當k優於t:
由於s[i]單調遞增,故若在狀態i下有k優於t,則對於任意v>i,存在k優於t。
這就意味著,如果我們在某個狀態時發現決策k優於t,我們便再也不需要訪問決策t了。這就利用決策單調性,達到了降低時間複雜度的效果。
此外,還可以發現,在某個狀態下的有效決策形成了乙個下凸殼。粗略證明如下:
設座標系中存在點a、b、c,其橫座標單調遞增,其對應決策簡稱為決策a、b、c
當b的縱座標大於a、c的縱座標(形成了乙個上凸殼):
2s[i]bc:決策a優於決策b,決策b優於決策c,故決策a最優;
kbc<2s[i]ab:決策a優於決策b,決策c優於決策b,故決策a或c最優;
2s[i]>kab:決策b優於決策a,決策c優於決策b,故決策c最優。
以上,形成上凸殼時,決策b不可能成為最優決策,故刪去點b,上凸殼性質被破壞;
同理,當b的縱座標小於a、c的縱座標(形成了乙個下凸殼):
2s[i]ab:決策a優於決策b,決策b優於決策c,故決策a最優;
kab<2s[i]bc:決策b優於決策a,決策b優於決策c,故決策b最優;
2s[i]>kbc:決策b優於決策a,決策c優於決策b,故決策c最優。
故形成下凸殼時,所有決策均有可能成為最優決策。
這樣,我們用乙個雙端佇列就能維護可能成為最優決策的的決策,始終保證隊首元素最優,佇列滿足下凸殼性質。
其實f陣列不需要開二維,因為我們每次只用到了f[i][j]和f[i][j-1],所以可以再壓去一維。但為方便理解,博主仍使用二維f陣列。
1 #include2bzoj4518-征途const
int maxn=3e3+10;3
intn,m;
4int
s[maxn];
5int
q[maxn],l,r;
6long
long
f[maxn][maxn];
7double count_y(int k,int j)
8double count(int t,int k,int j)
9int
main()
1018
for(int i=1;i<=n;++i)f[i][1]=s[i]*s[i];
19for(int j=2;j<=m;++j)
2030
}31 printf("
%lld\n
",f[n][m]*m-(long
long)s[n]*s[n]);
32return0;
33 }
oracle學習筆記4 效能調優
一 oracle的鎖分為2種 悲觀鎖定和樂觀鎖定。其中悲觀鎖定一般用在c s結構,要一直保持通話。樂觀鎖定有3種方式實現。1 加偽列,scn列。a 查詢的時候查出scn值,select scn b update的時候判斷scn的值是否與查詢的值相同,update where scn c update...
Log4j效能調優
不久前在系統中完成了監控的功能,監控系統的資訊量很大,使用者對頁面的每乙個點選都會產生記錄,每天下來的日誌量有2g多,我用log4j把這些監控記錄 放在日誌裡,然後進行非同步處理,但即使是這樣,記錄日誌會對磁碟io產生頻繁的訪問,而io通常就是系統的瓶頸所在。於是對log4j配置進行一些調優就 成了...
MYSQL基礎 引數調優 4 常見的快取調優引數
這篇文章整理一下快取相關常用的調優引數,並給出建議。此引數一起設定了臨時表的最大值。臨時表是mysql用於儲存中間結果,很多操作比如union 子查詢 join not in exist以及複雜的group by和order by都可能會使用到臨時表。僅在當前連線可見,當連線關閉時會自動釋放,另外在...