http://poj.org/problem?id=3666
题意比较简单
就是问改最少的次数
将一个序列变成一个单调序列
题解挺神的
每个数不会再改成除这个序列之外的数
如果能理解这个
那么对这个序列排下序
然后枚举每个位置的数
可以在n^2的复杂度内完成计算
很有意思
剩下的就是比较点单的DP了
AC代码:
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const ll N=2e3+10;
ll Abs(ll x){
if(x<0) return -x;
return x;
}
ll A[N],B[N],DP[N][N];
int main(){
ll n;
cin>>n;
for(ll i=1;i<=n;++i)
cin>>A[i],B[i]=A[i];
sort(B+1,B+1+n);
for(ll i=1;i<=n;++i){
ll a=DP[i-1][1];
for(ll j=1;j<=n;++j){
a=min(a,DP[i-1][j]);
DP[i][j]=a+Abs(A[i]-B[j]);
}
}
ll ans=DP[n][1];
for(ll i=2;i<=n;++i){
ans=min(ans,DP[n][i]);
}
sort(B+1,B+1+n,greater<ll>());
memset(DP,0,sizeof DP);
for(ll i=1;i<=n;++i){
ll a=DP[i-1][1];
for(ll j=1;j<=n;++j){
a=min(a,DP[i-1][j]);
DP[i][j]=a+Abs(A[i]-B[j]);
}
}
for(ll i=2;i<=n;++i){
ans=min(ans,DP[n][i]);
}
cout<<ans<<endl;
}