解析:
单调队列优化DP。
状态:表示到位置高度为的最小花费。
状态转移方程:
答案:
代码:
#include <bits/stdc++.h>
using namespace std;
const int Max=100010;
int n,c,ans=1e9;
int f[Max][105],h[Max];
deque<int>q;
inline int get_int()
{
int x=0,f=1;
char c;
for(c=getchar();(!isdigit(c))&&(c!='-');c=getchar());
if(c=='-') f=-1,c=getchar();
for(;isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+c-'0';
return x*f;
}
int main()
{
n=get_int(),c=get_int();
for(int i=1;i<=n;i++) h[i]=get_int();
for(int i=1;i<=100;i++)
if(i>=h[1]) f[1][i]=(i-h[1])*(i-h[1]);
else f[1][i]=1e9;
for(int i=2;i<=n;i++)
{
q.clear();
for(int j=100;j>=1;j--)
{
int pre=f[i-1][j]+c*j;
while(q.size()&&pre<q.back()) q.pop_back();
q.push_back(pre);f[i][j]=(j<h[i])?1e9:q.front()-c*j+(j-h[i])*(j-h[i]);
}
q.clear();
for(int j=1;j<=100;j++)
{
int pre=f[i-1][j]-c*j;
while(q.size()&&pre<q.back()) q.pop_back();
q.push_back(pre);f[i][j]=(j<h[i])?f[i][j]:min(q.front()+c*j+(j-h[i])*(j-h[i]),f[i][j]);
}
}
for(int i=1;i<=100;i++) ans=min(ans,f[n][i]);
cout<<ans;
return 0;
}