HDU3507列印文章 斜率優化入門

2021-09-25 11:40:50 字數 1264 閱讀 7677

題目描述

n<=500000 , m<=1000。

基本思路

根據題目,我們可以列出dp[i]=dp[j]+(a[i]-a[j])2+m,其中dp[i]表示i點是最後一段的最後乙個數字的最小花費,a[j]是字首和。但是這個dp式顯然是o(n2)的,我們考慮怎麼對它進行優化,化簡得:

dp[i]=dp[j]+a[i]2+a[j]2-2*a[i]*a[j]+m

由於這個dp式在計算時需要a[i]和a[j]的乘積,單調佇列就不能維護了。

斜率優化

半年多沒接觸,都不知道怎麼用它了……

接下來有一些玄學推導:

設用j更新比k更優,則:

dp[j]+a[i]2+a[j]2-2*a[i]*a[j]+m2+a[k]2-2*a[i]*a[k]

消去同類項:dp[j]+a[j]2-2*a[i]*a[j]2-2*a[i]*a[k]

移項:dp[j]-dp[k]+a[j]2-a[k]2

<2*a[i]*(a[j]-a[k])

我們設f[j]=dp[j]+a[j]2,f[k]=dp[k]+a[k]2

d p[

j]−a

[k]a

[j]−

a[k]

\frac

a[j]−a

[k]d

p[j]

−a[k

]​<2*a[i]

這個東西……是不是很像斜率

哈!這就是它為什麼要叫斜率優化。

具體實現

其實最重要的東西我都講了,我們可以用這個式子結合單調佇列維護凸包,就能過了。

看**吧。

#include

#define ll long long

const ll maxn =

500005

;ll read()

ll n,m,a[maxn]

,q[maxn]

,dp[maxn]

;ll slope_up

(ll j,ll k)

ll slope_down

(ll j,ll k)

intmain()

printf

("%lld\n"

,dp[n]);

}}

注:本篇題解只是斜率優化入門,沒有深究,後面做到難題時再補幾發部落格吧

HDU3507 斜率優化

r 題意 把n分成任意段 每段中連續 每一段代價 ci m 求總的最小代價 i l作為提醒自己的經驗題,即使再水也要記住坑點 其實是自己被坑的地方 斜率優化裸題 首先定義dp i 表示把前i個處理好的最小代價 dp i min 一看這個轉移就是n 2的,我們來搞成o n 的。h i m sum i ...

hdu 3507 斜率優化

我的第一道斜率優化。就這道題而言,寫出原始的方程 dp i min o n 2 的複雜度肯定超時,要麼優化轉移,要麼重寫方程。斜率優化的思想就是減少不必要的列舉 即不列舉肯定不會成為決策點的j 我們考慮兩個位置p 選擇q比選擇p優 當且僅當 dp q sum i sum q 2 m dp p sum...

hdu3507斜率優化dp

這題 n可能取500000,o n 2 就會超時吧,所有只能優化。注意到這題的動態規劃方程 dp i max dp j sum i sum j 2 m 化簡下得 dp i max dp j sum i 2 sum j 2 2 sum i sum j 無法直接用單調佇列優化,i和j不能分開。假設j比k...