Making the Grade POJ - 3666

//一开始要思考:到底是增好还是减好
//然后用dp,忽略这个问题 
//首先要明确的是,最终序列中的数字一定都是原序列中的数字 
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=2000+20;
int a[N];
int b[N];
int dp[N][N];
//dp[i,j],表示考虑前i个数变成单调,且最后一个数是b[j],此时的最小花费 
int main()
{
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
		cin>>a[i],b[i]=a[i];
	sort(b+1,b+1+n);
	//考虑到第一个数,最后一个数变成b[j]时的最小花费 
	for(int j=1;j<=n;j++)
		dp[1][j]=abs(a[1]-b[j]);
	//从第二位开始考虑 
	for(int i=2;i<=n;i++)
	{
		//考虑到i-1位,变成单调,最后一个变成b1 
		int pre=dp[i-1][1];
		for(int j=1;j<=n;j++)
		{
			//考虑i-1位,变成单调,最后一个变成b[j]的最小花费 
			pre=min(pre,dp[i-1][j]);
			//考虑i位,变成单调,那么下一位变成b[j]的代价 
			dp[i][j]=pre+abs(a[i]-b[j]);
		}
	}
	cout << *min_element(dp[n]+1, dp[n] + n +1) << endl;
}
posted @ 2020-03-14 11:33  晴屿  阅读(78)  评论(0编辑  收藏  举报