题目大意:
N个数表示每个点的海拔,题目是问你改如何花最少的花费,将N个点的海拔调整成非严格递增或非严格递减
分析:
dp。dp[i][j]表示前i个,j为最大数的非严格递增或非严格递减序列所需的最小花费,但是题目中的j其实是很大, 可是j的个数很少,所以dp[i][j]中j的含义改成,B中第j个元素为最大数,前i个的最少花费,状态转移方程也可以 得出了dp[i][j]=min(dp[i-1][k])+abs(a[i]-b[j])详细看代码
code:
#define debug #include<stdio.h> #include<math.h> #include<cmath> #include<queue> #include<stack> #include<string> #include<cstring> #include<string.h> #include<algorithm> #include<iostream> #include<vector> #include<functional> #include<iomanip> #include<map> #include<set> #define pb push_back #define dbg(x) cout<<#x<<" = "<<(x)<<endl; #define lson l,m,rt<<1 #define cmm(x) cout<<"("<<(x)<<")"; #define rson m+1,r,rt<<1|1 using namespace std; typedef long long ll; const int maxn=1e5; const int INF=0x3f3f3f3f; const ll inf=0x7fffff; const int mod=1e9+7; const int MOD=10007; //---- //define ll a[maxn]; ll b[maxn]; ll dp[2005][2005]; //solve void solve() { int n; cin>>n; for(int i=1;i<=n;i++){ cin>>a[i]; b[i]=a[i]; } sort(b+1,b+1+n); for(int i=1;i<=n;i++){ ll mi=dp[i-1][1]; for(int j=1;j<=n;j++){ mi=min(mi,dp[i-1][j]); dp[i][j]=mi+llabs(a[i]-b[j]); } } ll mi=INF; for(int i=1;i<=n;i++){ mi=min(mi,dp[n][i]); } cout<<mi<<endl; } int main() { ios_base::sync_with_stdio(0); #ifdef debug freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); #endif cin.tie(0); cout.tie(0); solve(); return 0; }