这题和POJ3666是一样的题目,只是数据范围扩大了,从2000扩大到了5000,做法和POJ3666是一样的,只需扩展数组大小即可,所以就不赘述了,全当我极不负责的水了一篇博客好了。。。,POJ3666的解释可以看这里。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long LL;
LL s[5005]= {0};
LL cop[5005]= {0};
LL dp[5005]= {0};
bool cmp(LL a,LL b)
{
return a>b;
}
LL Abs(LL a)
{
if(a>=0)return a;
else return -a;
}
int main()
{
//freopen("in.in","r",stdin);
int n;
scanf("%d",&n);
for(int i=0; i<n; i++)
{
scanf("%lld",&s[i]);
cop[i]=s[i];
}
//
sort(cop,cop+n);//非递减
for(int i=0; i<n; i++) //初始化
dp[i]=Abs(s[0]-cop[i]);
for(int i=1; i<n; i++) //dp
{
LL temp=dp[0];
for(int j=0; j<n; j++)
{
temp=min(dp[j],temp);
dp[j]=temp+Abs(s[i]-cop[j]);
}
}
LL ans=dp[0];
for(int i=0; i<n; i++)
ans=min(dp[i],ans);
///
sort(cop,cop+n,cmp);//非递增
for(int i=0; i<n; i++) //初始化
dp[i]=Abs(s[0]-cop[i]);
for(int i=0; i<n; i++) //dp
{
LL temp=dp[0];
for(int j=0; j<n; j++)
{
temp=min(dp[j],temp);
dp[j]=temp+Abs(s[i+1]-cop[j]);
}
}
LL ANS=dp[0];
for(int i=0; i<n; i++)
ANS=min(dp[i],ANS);
ans=min(ans,ANS);
printf("%lld\n",ans);
return 0;
}