p教授要去看奧運,但是他捨不下他的玩具,於是他決定把所有的玩具運到北京。傳送門他使用自己的壓縮器進行壓縮,其可以將任意物品變成一堆,再放到一種特殊的一維容器中。
p教授有編號為\(1...n\)的\(n\)件玩具,第i件玩具經過壓縮後變成一維長度為\(ci\)。
為了方便整理,p教授要求在乙個一維容器中的玩具編號是連續的。
同時如果乙個一維容器中有多個玩具,那麼兩件玩具之間要加入乙個單位長度的填充物。形式地說如果將第\(i\)件玩具到第\(j\)個玩具放到乙個容器中,那麼容器的長度將為\(x = j - i + \sum_^ck\)。
製作容器的費用與容器的長度有關,根據教授研究,如果容器長度為\(x\),其製作費用為\((x-l)^2\)。其中\(l\)是乙個常量。
p教授不關心容器的數目,他可以製作出任意長度的容器,甚至超過l。但他希望費用最小。
輸入格式:第一行輸入兩個整數\(n,l\)。接下來\(n\)行輸入\(ci\)。\(1 \leqslant n \leqslant 50000,1 \leqslant l,ci \leqslant 10^7\)
輸出格式:輸出最小費用。
輸入樣例#1:
輸出樣例#1:5 434
214
1
首先我們容易得到轉移方程\(dp[i] = min(dp[j] + (i - j - 1 + sum[i] - sum[j] - l)^)(j < i)\),其中\(sum[i]\)表示\(c[i]\)從\(1\)到\(i\)的字首和,\(dp[i]\)為分組完前\(i\)件物品的最小花費。
因為這方程是顯然的二維dp,所以一定過不了。設\(g[i] = sum[i] +i,l = l + 1\)。
我們把方程化簡:
\[dp[i] = dp[j] + (i - j + sum[i] - sum[j] - l)^2\\
dp[i] = dp[j] + (g[i] - g[j] - l)^2\\
dp[i] = dp[j] + g[i]^2 - 2g[i](g[j] + l) + (g[j] + l)^2\\
dp[i] = dp[j] + g[i]^2 - 2g[i]g[j] - 2g[i]l + g[j]^2 + 2g[j]l + l^2\\
} = } } }\\
}= } } }
\]所以就可以斜率優化了。單調佇列維護下凸包即可。
這簡直是乙個模板:p
**:
還有,多說一句,這題有決策單調性,而且出題人沒有卡掉。所以也可以#include #include typedef long long ll;
const int maxn = 50010;
const ll inf = 0x7fffffffffffff;
int n, l;
ll sum[maxn], f[maxn];
inline ll pow(ll x)
inline ll y(int x)
inline double calcb(int x, int y)
struct ddstack
void push(int x)
int pop(int i)
}s;int main()
printf("%lld\n", f[n]);
return 0;
}
親測能過。int p = 0;
for (int i = 1; i <= n; ++i)
for (int j = p; j < i; ++j)
HNOI2008 玩具裝箱
p教授要去看奧運,但是他捨不下他的玩具,於是他決定把所有的玩具運到北京。他使用自己的壓縮器進行壓 縮,其可以將任意物品變成一堆,再放到一種特殊的一維容器中。p教授有編號為1.n的n件玩具,第i件玩具經過 壓縮後變成一維長度為ci.為了方便整理,p教授要求在乙個一維容器中的玩具編號是連續的。同時如果乙...
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 ...