Title link
set \ (d [i] \) of the front of \ (I \) required to give a toy boxed minimum cost
readily available dynamic transfer equation:
\ [D [I] = min (D [J] + (s [i] -s [j
] + ij-1-L) ^ 2), (j <i) \] where \ (S [I] = \ ^ sum_1 [I] \) iC , the complexity of ordinary DP is \ (O (^ n-2) \) . After optimization of the slope will become \ (O (n-) \) .
Careful observation we can make ease of representation \ (f [i] = s
[i] + i \) then the equation becomes
\ [D [i] = min (d [j] + (f [i] -f [j] -1-L) ^ 2) \]
We discuss \ (j_1, j_2 (1 \ le j_1 <j_2 <i) \) decision, assuming that \ (j_2 \) than \ (j_1 \) better, then there
\(d[j_1] + (f[i] -f[j_1]-1-L)^2 \ge d[j_2]+(f[i]-f[j_2]-1-L)^2\)
Expanded get
\(d[j_1] + f[i]^2 - 2\times f[i]\times (f[j_1]+1+L)+(f[j_1]+1+L)^2 \ge d[j_2]+f[i]^2-2\times f[i]\times (f[j_2]+1+L)+(f[j_2]+1+L)^2\)
After transposition available
\(2\cdot f[i]\ge {d[j_2]+(f[j_2]+1+L)^2-d[j_1]-(f[j_1]+1+L)^2 \over f[j_2]-f[j_1]}\)
Order \ (G [I] = F [I]. 1 + L + \) , there
\(2\cdot f[i]\ge {(d[j_2]+g[j_2])-(d[j_1]+g[j_1])\over f[j_2]-f[j_1]}\)
Therefore, by maintaining a queue decision set, when the \ (j_1 <j_2 \) , the above equation is satisfied and, \ (j_1 \) dequeued.
Also, because \ (f [i] \) with \ (I \) monotonically. So calculate \ (d [i] \) then you want to \ (i \) when the team can not be ruled out in time element for decision-making.
How to calculate? The slope of the tail should monotone, holding with \ (f [i] \) is consistent with the monotonicity can.
#include <bits/stdc++.h>
using namespace std;
const int N = 50010;
typedef long long ll;
typedef long double db;
db c[N],d[N],f[N],s[N],g[N];
int n,L;
int q[N],l,r;
db sqr(db x){return x * x;}
db slope(int i,int j){
return ((d[i] + g[i]) - (d[j] + g[j])) / (f[i] - f[j]);
}
int main(){
scanf("%d%d",&n,&L);
l=r=1;
for(int i=1;i<=n;i++){
cin>>c[i];
s[i]=s[i-1] + c[i];
f[i] = s[i] + i;
g[i] = (f[i] + 1 + L) * (f[i] + 1 + L);
}
g[0] = (ll)(1+L)*(1+L);//注意0号元素的g值初始化
for(int i=1;i<=n;i++){
while(l < r && slope(q[l],q[l+1]) < 2 * f[i])l++;
int j = q[l];
d[i] = d[j] + sqr(f[i]-f[j]-1-L);
while(l < r && slope(q[r],q[r-1]) > slope(i,q[r-1]))r--;//满足队尾斜率单调性
q[++r] = i;//入队
}
printf("%lld\n",(ll)d[n]);
return 0;
}