f
i
=
min
j
<
i
a
i
+
f
j
+
1
+
2
+
⋯
+
(
i
−
j
−
1
)
(
j
为
i
左
边
第
一
个
城
堡
)
f_i=\min\limits_{j<i}{a_i+f_j+1+2+\dots+(i-j-1)} (j为i左边第一个城堡)
fi=j<iminai+fj+1+2+⋯+(i−j−1)(j为i左边第一个城堡)
化
简
得
f
i
=
min
j
<
i
a
i
+
f
j
+
(
i
−
j
)
×
(
i
−
j
−
1
)
化简得 f_i=\min\limits_{j<i}{a_i+f_j+(i-j)\times(i-j-1)}
化简得fi=j<iminai+fj+(i−j)×(i−j−1)
f
i
=
min
j
<
i
f
j
+
j
(
j
−
1
)
2
+
i
j
+
a
i
+
i
(
i
−
1
)
2
f_i=\min\limits_{j<i}{f_j+\frac{j(j-1)}{2}+ij+a_i+\frac{i(i-1)}{2}}
fi=j<iminfj+2j(j−1)+ij+ai+2i(i−1)
设
x
j
=
j
,
y
j
=
f
j
+
j
(
j
−
1
)
2
设x_j=j, y_j=f_j+\frac{j(j-1)}{2}
设xj=j,yj=fj+2j(j−1)
然后斜率优化
调试记录
\(\ y_j\)找错
#include<cstdio>#include<algorithm>#include<cstring>#define INF 0x3f3f3f3f#define maxn 1000005#define int long longusingnamespace std;int f[maxn], q[maxn], a[maxn];int l, r, n, sum[maxn];intY(int id){return f[id]+ sum[id];}doubleslope(int id1,int id2){return1.0*(Y(id2)-Y(id1))/(id2 - id1);}signedmain(){scanf("%lld",&n); sum[0]=0;for(int i =1; i <= n; i++){scanf("%lld",&a[i]);
sum[i]= sum[i -1]+ i;}
l =0, r =0;for(int i =1; i <= n; i++){while(l < r &&slope(q[l], q[l +1])<= i) l++;int j = q[l];
f[i]=Y(j)- i * j + a[i]+ sum[i -1];while(l < r &&slope(q[r -1], q[r])>=slope(q[r], i)) r--;
q[++r]= i;}printf("%lld\n", f[n]);return0;}