poj3666(DP+离散化)

题目链接: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 }

猜你喜欢

转载自www.cnblogs.com/FrankChen831X/p/10449459.html