题意:给你一串数字,求要使这串数字变成一串非降数列的最小花费
思路:看了题解才知道,最后形成的非降数列中的元素一定是存在于原数列里的元素,那么定义两个数组num[i]=b[i],将num从小到大排序。
设dp[i][j]表示前i个原数组数字,用不超过num[j]形成非降数列的最小花费,则可得出状态方程
dp[i][j]=min(dp[i][j-1],dp[i-1][j]+|num[j]-b[i]|);(i>0,j>0);
dp[0][0]=|num[0]-b[0]|;
dp[0][j]=min(dp[0][j-1],|num[j]-b[0]|)(j>0);
dp[i][0]=dp[i-1][0]+|num[0]-num[i]|(i>0);
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
inline __int64 mabs(__int64 a)
{
return a<0?(-a):a;
}
inline __int64 min(__int64 a,__int64 b)
{
return a<b?a:b;
}
__int64 num[5005];
__int64 dp[5005];
__int64 b[5005];
int n;
int main()
{
while(cin>>n)
{
for(int i=0;i<n;i++)
{
cin>>num[i];
b[i]=num[i];
dp[i]=0;
}
sort(num,num+n);
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
if(j==0) dp[j]+=mabs(num[j]-b[i]);
else dp[j]=min(dp[j-1],dp[j]+mabs(num[j]-b[i]));
}
cout<<dp[n-1]<<endl;
}
return 0;
}