蹦蹦跳跳結束後,cxt回頭看看本身走過的路坑坑窪窪的,心中很是不爽,他表示要把這段路的路面高度修成單調上升的或者單調降低的,整條路能夠當作 N段,N個整數A1,…..,An(1<=n<=2000)依次描述了每一段路的高度(0<=Ai<=1000000000)。 但願找到一個剛好含N個元素的不上升或不降低的序列B1,……,Bn,做爲修過的路中每一個路段的高度。ios
因爲將每一段路墊高或挖低一個單位消耗的體力相同,因而能夠表示爲:spa
|A1-B1|+|A2-B2|+…..+|An-Bn|code
請你計算一下,要修好這段道路,最少消耗多少體力。消耗的整體力不會超過2^31-1orm
輸入文件的第一行僅有一正整數N,如下的N行每行一個整數Ai,表示路面的高度。排序
輸出文件僅有一個正整數,表示若是把路修成高度不上升或不降低的最小花費ip
7 1 3 2 4 5 3 9
3
將第一個高度爲3的路段的高度減小爲2,將第二個高度爲3的路段的高度增長到5,總花費爲|2-3|+|5-3|=3,而且各路段的高度爲一個不降低序列 1,2,2,4,5,5,9。ci
================================it
題解正文io
================================class
題目分析
這是一道動態規劃題目,求最小花費使道路變成不嚴格單調遞增或不嚴格單調遞減,數據大小用int便可。
#include<iostream> #include<cmath> #include<algorithm> using namespace std; int n,ans=1<<30,a[2005],c[2005],f[2005][2005],g[2005][2005]; void init() { cin>>n; for(int i = 1; i <= n ; ++i) { cin >> a[i]; c[i]=a[i]; } sort(c+1,c+n+1); } void sol() { for(int i = 1; i <= n; ++i) { for(int j = 1; j <= n; ++j) { f[i][j] = g[i-1][j] + abs(a[i]-c[j]); if(j == 1) g[i][j] = f[i][j]; else g[i][j] = min(f[i][j],g[i][j-1]); } } for(int i = 1; i <= n; ++i) ans = min(ans ,f[n][i]); } int main() { init(); sol();//算一遍遞增 for(int i = 1; i <= n/2 ; ++i) swap(c[i],c[n-i+1]); sol();//算一遍遞減 cout<<ans; }