题目链接:http://poj.org/problem?id=3666
思路:
看了讨论区说本题的数据比较弱,只需要考虑不减序列即可,比较懒,所以我也只写了这一部分的代码,思路都一样,能AC就行了。
首先要想明白一点,就是将每一个elevation更新后的值一定是原来存在的,因为更新一个elevation最好是与前一个相等,要么与后一个相等,可以从贪心角度去想,这里要先明白,很重要。所以我们将原始数据存在a数组中,将a数组按升序排序后存在b中。用dp[i][j]表示a数组前i个数据中最后一个数据是b[j]的最小代价,则状态转移方程即为:dp[i][j]=dp[i-1][k]+abs(b[j]-a[i]) (k<=j)。因为求dp[i][j]时只会用到dp[i-1][k],所以可以用滚动数组,使空间大大节省。详见代码:
#include<cstdio>
#include<algorithm>
using namespace std; int n,res=0x3f3f3f3f;
int a[],b[],dp[]; int main(){
scanf("%d",&n);
for(int i=;i<=n;++i){
scanf("%d",&a[i]);
b[i]=a[i];
}
sort(b+,b+n+);
for(int i=;i<=n;++i){
int tmp=0x3f3f3f3f;
for(int j=;j<=n;++j){
tmp=min(tmp,dp[j]);
dp[j]=tmp+abs(b[j]-a[i]);
}
}
for(int i=;i<=n;++i)
res=min(res,dp[i]);
printf("%d\n",res);
return ;
}