dp i j 表示第i个位置填第B[j]时的最小代价
#include<stdio.h> #include<iostream> #include<algorithm> #include<vector> #include<math.h> using namespace std; #define int long long #define si signed #define sc(x) scanf("%lld",&x); #define maxn 3009 #define abs llabs int A[maxn]; vector<int> v; int B[maxn]; int dp[maxn][maxn]; int n; si main() { sc(n); for(int i=1;i<=n;i++){ sc(A[i]); v.push_back(A[i]); } sort(v.begin(),v.end()); int sz=unique(v.begin(),v.end())-v.begin(); for(int i=0;i<sz;i++){ B[i]=v[i]; } for(int i=1;i<=n;i++){ int val=1e18; for(int j=0;j<sz;j++){ val=min(val,dp[i-1][j]); dp[i][j]=val+abs(A[i]-B[j]); } } int ans=1e18; for(int i=0;i<sz;i++){ ans=min(ans,dp[n][i]); } for(int i=1;i<=n;i++){ int val=1e18; for(int j=sz-1;j>=0;j--){ val=min(val,dp[i-1][j]); dp[i][j]=val+abs(A[i]-B[j]); } } for(int i=0;i<sz;i++){ ans=min(ans,dp[n][i]); } cout<<ans<<' '; }