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; }