斜率優化dp練習

2022-05-09 14:39:10 字數 3389 閱讀 4057

1.hdu3507

裸題,有助於理解斜率優化的精髓。

dp[i]=min(dp[j]+m+(sum[i]-sum[j])2)

很顯然不是單調佇列。

根據斜率優化的的定義,就是先設兩個決策j,k

什麼時候我們認為在 i 的環境下 j 比 k 好呢?根據上面的遞推式,得到下面這麼乙個式子

dp[j]+m+(sum[i]-sum[j])2

2開啟括號:

dp[j]+m+sum[i]2+sum[j]2-2*sum[i]*sum[j]2+sum[k]2-2*sum[i]*sum[k]

移項,將有 i 的項移到右側:

dp[j]+sum[j]2-dp[k]-sum[k]2

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

除下來:

(dp[j]+sum[j]2-dp[k]-sum[k]2)/[2*(sum[j]-sum[k])]好了這就是斜率了^_^

1 #include2 #include3 #include4 typedef long

long

lnt;

5int q[1000000

];6 lnt sum[1000000

];7 lnt dp[1000000];8

inth,t;

9lnt n;

10lnt m;

11 lnt x(int

x)12

15 lnt tp(int i,int

j)16

19 lnt btm(int i,int

j)20

23int

main()

2444 printf("

%lld\n

",dp[n]);45}

46return0;

47 }

2.bzoj1010: [hnoi2008]玩具裝箱toy

這道題依然斜率單調

dp方程自己推:

dp[i]=min(dp[j]+(i-j-1+sum[i]-sum[j]-l)2)

依然假設在 i 的環境下決策 j 優於 k 

那麼:dp[j]+(i-j-1+sum[i]-sum[j]-l)2

2將常數項與與 i 有關的項放到一起,展開:

(sum[j]+j)2-2*(i+sum[i]-l-1)*(sum[j]+j)+dp[j]<(sum[k]+k)2-2*(i+sum[i]-l-1)*(sum[k]+k)+dp[k]

設函式 f(x)=sum[x]+x , h(x)=x+sum[x]-l-1 , g(x)=dp[x]+f(x)2

得到當:

g(j)-g(k)<2*h(i)*(f(j)-f(k)) 時,j 比 k 優秀。

f(x)單調遞增,斜率單調。

時間複雜度o(n)

**:

1 #include2 #include3 #include4 typedef long

long

lnt;

5 lnt sum[1000000

];6 lnt dp[1000000];7

int q[1000000];8

inth,t;

9int

n;10

lnt l;

11 lnt f(int

x)12

15 lnt k(int

x)16

19 lnt g(int

x)20

23lnt squ(lnt x)

2427

intmain()

2835 q[1]=0

;36 dp[0]=0

;37 h=t=1;38

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

3947 printf("

%lld\n

",dp[n]);

48return0;

49 }

3.bzoj1911: [apio2010]特別行動隊

斜率單調。

方程自己推:

設:g(x)=a*x2+b*x+c

dp[i]=max(dp[j]+g(sum[i]-sum[j]))

設在 i 環境下決策 j 優於 k

dp[j]+g(sum[i]-sum[j])>dp[k]+g(sum[i]-sum[k])

設f(x)=dp[x]+a*sum[x]2-b*sum[x]

則當:f(j)-f(k)>2*a*sum[i]*(sum[j]-sum[k])

設 j > k 斜率單調

時間複雜度o(n)

**:

1 #include2 #include3 #include4 typedef long

long

lnt;

5 lnt sum[1000006

];6 lnt dp[1000006];7

int q[1000006];8

inth,t;

9int

n;10

lnt a,b,c;

11 lnt f(int

x)12

15lnt g(lnt x)

1619

int main(void)20

30 q[1]=0

;31 dp[0]=0;32

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

3341 printf("

%lld\n

",dp[n]);

42return0;

43 }

4.bzoj4518: [sdoi2016]征途

這次變成二維的了。

都一樣,展開方程+斜率優化。

這次要對於每一天進行o(n)轉移,共m天,時間複雜度o(n*m)

**:

1 #include2 #include3 #include4 typedef long

long

lnt;

5 lnt dp[4000][4000

];6 lnt sum[10000];7

int q[1000000];8

lnt n,m;

9lnt l;

10int

h,t;

11lnt squ(lnt x)

1215 lnt f(int x,int

i)16

19int

main()

2027 l=sum[n];

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

2932

for(int d=2;d<=m;d++)

3345

}46 printf("

%lld\n

",dp[n][m]+squ(l));

47return0;

48 }

斜率優化 DP

我們知道,有些dp方程可以轉化成dp i f j x i 的形式,其中f j 中儲存了只與j相關的量。這樣的dp方程我們可以用單調佇列進行優化,從而使得o n 2 的複雜度降到o n 可是並不是所有的方程都可以轉化成上面的形式,舉個例子 dp i dp j x i x j x i x j 如果把右邊...

dp斜率優化

我們知道,有些dp方程可以轉化成dp i f j x i 的形式,其中f j 中儲存了只與j相關的量。這樣的dp方程我們可以用單調佇列進行優化,從而使得o n 2 的複雜度降到o n 可是並不是所有的方程都可以轉化成上面的形式,舉個例子 dp i dp j x i x j x i x j 如果把右邊...

斜率優化DP

斜率優化主要解決的是轉移方程中存在乙個同時與i和j有關的部分時的優化問題 dp i min dp j a i b j 0 include using namespace std typedef long long ll const int maxn 1e5 5 ll a maxn b maxn dp...