題目鏈結
題意:有編號為\(1\cdots n\)的n件玩具,第 i 件玩具經過壓縮後變成一維長度為 \(c_i\) 。要求在乙個容器中的玩具編號是連續的,同時如果將第 i 件玩具到第 j 個玩具放到乙個容器中,那麼容器的長度將為 \(x=j-i+\sum\limits_^c_k\)。如果容器長度為 x ,其製作費用為 \((x-l)^2\) .其中 l 是乙個常量。容器數目長度不限。求最小費用。
\(1 \le n \le 50000,1 \le l,ci \le 10^7\)
這道題是斜率優化的經典題了qvq
當然dp順序肯定是從前到後了
分析一下答案式
用f(j)來更新f(i)
\[x - l = i-(j + 1)+\sum\limits_^c_k - l= sum[i] + i - sum[j] - j - l - 1
\]設\(a[i] = sum[i] + i, b[i] = sum[i] + i + 1 + l\)
\[f[i] = f[j] + (x - l)^2 = f(j) + (a[i] - b[j]) ^ 2
\]這裡面 隨j改變的量是\(b[j], b[j]^2\)和\(f[j]\)
所以移項得 \(2⋅a[i]⋅b[j]+f[i]−a[i]^2=f[j]+b[j]^2\)
將b[j]看作x,\(f[j]+b[j]^2\)看作y,這個式子就可以看作一條斜率為\(2a[i]\)的直線
f[i]即當上述直線過點\(p(b[j],f[j]+b[j]^2)\)時,直線在y軸的截距加\(a[i]^2\)
而題目即為找這個截距的最小值
由於sum[i]隨i遞增 所以a[i],b[i]都遞增
所以點\(1 \cdots i-1\)是從左到右排列的
用單調棧維護一下凸包
像做線性規劃一樣做乙個切線就行了
也就是二分斜率\((p_j,p_) < 2a[i]\)
update:貌似不用二分
因為a[i]遞增要查詢的斜率也遞增
那單調佇列維護就行了qvq
#include#include#include#includeusing namespace std;
const int n = 1e5 + 5;
const int k = 2e5;
int n, l;
double sum[n], f[n];
int que[n], head, tail;
inline double a(int x)
inline double b(int x)
inline double x(int x)
inline double y(int x)//注意這裡不可以用define qvq
//a[i] = sum[i] + i, b[i] = sum[i] + i + 1 + l
//p(b[j],f[j]+b[j]^2)
inline double slope(int x, int y)
int main()
head = tail = 1;
for(int i = 1; i <= n; ++i)
printf("%lld", (long long)f[n]);
return 0;
}
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教授要求在乙個一維容器中的玩具編號是連續的。同時...