开始和kxy推了半天都没推出sample,就没感多想这道题怎么做,先放下了,结果换MT来看这道题,瞬间就推出了sample。
一切都变得清晰起来,简单动态规划。
朴素的转移方程:
dp[i][j]=min(dp[i][k]+abs(j-k)+(j-a[i])^2) dp[i][j]表示到第i个高度为j的最小代价
由于复杂度100000*100*100会超时,利用分类讨论(j<k和j>=k),将k维度用两个数组预处理出来就解决了。
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
#define N 100005
#define M 105
#define inf 0x3f3f3f3f
#define ABS(a) ((a)<0?(-(a)):(a))
int dp[M], a[N],low[N],high[N],f[N];
int main()
{
int n, m, i, j, c, mi, mxlen=0, k, tp;
scanf("%d%d", &n, &c);
for(i=0; i<n; i++)
{
scanf("%d", a+i);
if(mxlen < a[i]) mxlen = a[i];
}
memset(dp, 0x3f, sizeof(dp));
for(i=a[0]; i<=100; i++)
dp[i] = (i-a[0])*(i-a[0]);
for(i=1; i<n; i++)
{
memcpy(f,dp,sizeof(dp));
for(j=0;j<=100;j++)
dp[j]=low[j]=high[j]=inf;
low[0]=f[0];
for(j=1;j<=100;j++)
low[j]=min(low[j-1],f[j]-c*j);
high[100]=f[100]+100*c;
for(j=99;j>=0;j--)
high[j]=min(high[j+1],f[j]+c*j);
for(j=a[i];j<=100;j++)
dp[j]=min(high[j]-c*j,low[j]+c*j)+(j-a[i])*(j-a[i]);
}
mi = inf;
for(i=a[n-1];i<=100; i++)
if(mi>dp[i])
mi=dp[i];
printf("%d\n",mi);
return 0;
}