http://blog.csdn.net/miracle_ma/article/details/52537208
然后我又想了想为什么不能跳过ai-i,然后dp时循环到j-1。
原因是ai的范围是1到1e9,如果直接dp严格递增,那么dp就得从1循环到1e9,这样无论是在空间还是时间上都是不允许的。
然而转化ai-i后,问题转化成了非严格递增,那么答案就可以在这3000个数中找,那么可以把3000个数离散化,这样dp就最多只需要从1循环到3000。
代码
#include<bits/stdc++.h>
#define maxn 3010
using namespace std;
typedef long long ll;
ll n;
ll a[maxn];
ll b[maxn];
ll MIN[maxn];
ll dp[maxn][maxn];
int main()
{
scanf("%I64d",&n);
for(ll i=0;i<n;i++)
{
scanf("%I64d",&a[i]);
a[i]-=i;
b[i]=a[i];
}
sort(a,a+n);
ll tot=unique(a,a+n)-a;
for(ll i=0;i<tot;i++)
{
dp[0][i]=abs(b[0]-a[i]);
if(i) MIN[i]=min(MIN[i-1],dp[0][i]);
else MIN[i]=dp[0][i];
}
for(ll i=1;i<n;i++)
for(ll j=0;j<tot;j++)
{
dp[i][j]=MIN[j]+abs(b[i]-a[j]);
if(j) MIN[j]=min(MIN[j-1],dp[i][j]);
else MIN[j]=dp[i][j];
}
ll ans=1e18;
for(ll i=0;i<tot;i++)
ans=min(ans,dp[n-1][i]);
printf("%I64d\n",ans);
return 0;
}