HNOI2008 玩具裝箱toy(斜率優化dp)

2022-05-02 20:33:07 字數 1675 閱讀 9928

前言

這是我寫的第一道$dp$斜率優化的題目,$dp$一直都很菜,而且咖啡雞都說了這是基礎的東西,然而看別人對$dp$斜率優化一大堆公式又看不懂就老老實實做幾道題目,這個比較實在

描述

給出$n$和$l$.有$n$個玩具,第$i$個玩具的長度是$c[i]$,要求將玩具分成若干段,從$i$到$j$分為一段的長度為$x=j-i+\sum_^c[k]$,費用為$(x-l)^$. 求最小費用    [link]

分析

用$dp[i]$表示前i個玩具所需的最小費用,則有

$dp[i]=min\left \(1<=j

其中$sum[i]$表示的是$c[i]$的字首和.

為了方便,我們設

$a[i]=sum[i]+i,l=l+1$

於是原方程就等價於

$dp[i]=min\left\(1<=j

我們設$j

$dp[k]+(a[i]−a[k]−l)^

在紙上寫寫畫畫,把式子開啟再變一下形,容易得到

$\frac]-[dp[j]+(a[j]+l)^]}$ $

是不是很像

$\frac-y_}-x_}$

的形式?

這玩意兒不就是斜率嗎?!我們設它為$g(k,j)$

我們可以發現$a[i]$是單調遞增的,所以所有決策可以轉化為二維空間上的點集.

也就是說$k$這個點和j這個點的連線的斜率如果小於$a[i]$,那麼$k$這個決策就更優.

那麼對於三個決策$a

1.如果$g(b,a)

2.如果$g(b,a)>=a[i]$,那麼$b$不是最優,最優可能是$a$或$c$.

所以我們在新加入乙個點的時候,就可以把它看作$c$,然後把所有這樣的$b$都去掉,直到$g(c,b)>g(b,a)$,所以我們需要處理的斜率是單調遞增的.

這樣我們就可以用乙個單調佇列分別維護隊首和隊尾啦.

code

#include #define ll long long

#define empty (head>=tail)

const

int maxn = 5e4+10

;ll n, l, head, tail, j;

ll q[maxn], sum[maxn], s[maxn], f[maxn];

inline

double x(ll i)

inline

double y(ll i)

inline

double rate(ll i,ll k)

intmain()

head = tail = 1; q[1] = 0

;

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

printf(

"%lld\n

", f[n]);

}

view code

網上講了很多數形結合的方法,找截距最小,的確對理解很有幫助,但是可能像這樣的對我來說更好理解,另外有些細枝末節的東西沒有完全看懂,但是現在沒必要糾結.

建議多看些部落格,了解不同的想法,慢慢就會理解

這裡能用斜率優化是因為a[i]是單調的,至於具體為什麼,先不細究

參考文章:

HNOI2008 玩具裝箱toy

重點在講斜率優化 description p教授要去看奧運,但是他捨不下他的玩具,於是他決定把所有的玩具運到北京。他使用自己的壓縮器進行壓縮,其可以將任意物品變成一堆,再放到一種特殊的一維容器中。p教授有編號為1.n的n件玩具,第i件玩具經過壓縮後變成一維長度為ci.為了方便整理,p教授要求在乙個一...

HNOI2008 玩具裝箱toy

dp i min dp j sum i sum j c 2 dp k sum i sum k c 2 dp k si sum k 2 dp k si 2 2 si sum k sum k 2 dp k sum k 2 dp j sum j 2 2 si sum k sum j yk yj 2 si ...

HNOI2008 玩具裝箱TOY

題目描述 p教授要去看奧運,但是他捨不下他的玩具,於是他決定把所有的玩具運到北京。他使用自己的壓縮器進行壓縮,其可以將任意物品變成一堆,再放到一種特殊的一維容器中。p教授有編號為1 n的n件玩具,第i件玩具經過壓縮後變成一維長度為ci.為了方便整理,p教授要求在乙個一維容器中的玩具編號是連續的。同時...