题目链接: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],所以可以用滚动数组,使空间大大节省。详见代码:
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 5 int n,res=0x3f3f3f3f; 6 int a[2005],b[2005],dp[2005]; 7 8 int main(){ 9 scanf("%d",&n); 10 for(int i=1;i<=n;++i){ 11 scanf("%d",&a[i]); 12 b[i]=a[i]; 13 } 14 sort(b+1,b+n+1); 15 for(int i=1;i<=n;++i){ 16 int tmp=0x3f3f3f3f; 17 for(int j=1;j<=n;++j){ 18 tmp=min(tmp,dp[j]); 19 dp[j]=tmp+abs(b[j]-a[i]); 20 } 21 } 22 for(int i=1;i<=n;++i) 23 res=min(res,dp[i]); 24 printf("%d\n",res); 25 return 0; 26 }