【暑假】[深入动态规划]UVa 12170 Easy Climb

UVa 12170 Easy Climb

 

题目:

http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=24844

思路:

 引别人一个题解琢磨一下:

 

  from:http://blog.csdn.net/glqac/article/details/45257659

代码:

 1 #include<iostream>
 2 #include<algorithm>
 4 #define FOR(a,b,c) for(int a=(b);a<(c);a++)
 5 using namespace std;
 6 
 7 typedef long long LL;
 8 
 9 const int maxn = 100 + 5;
10 const int maxx = maxn*maxn*2;
11 const LL INF = (1LL << 60);
12 
13 LL h[maxn],x[maxx],dp[2][maxx];
14 
15 int main() {
16     int T; cin>>T;
17     while(T--) {
18         int n; LL d;
19         cin>>n>>d;
20         FOR(i,0,n) cin>>h[i];
21         if(abs(h[0]-h[n-1])> (n-1)*d) { //input无解 
22             cout<<"impossible\n";
23             continue;
24         }
25         
26         int nx=0;
27         FOR(i,0,n) 
28           FOR(j,-(n-1),n) //-(n-1)..(n-1)
29               x[nx++]=h[i]+j*d;
30         sort(x,x+nx);  //从小到大单调增长 
31         nx=unique(x,x+nx)-x; //去重且返回最终尾标  //x构造为修改后的所有可能取值 
32         
33         FOR(i,0,nx) {  //dp_init
34             dp[0][i]=INF;                                                             
35             if(x[i]==h[0]) dp[0][i]=0; //原本第i个就是h[0] //第0个数不能修改 
36         } 
37         
38         //d[i][j]意味着已经修改i个数其中第i个数修改成为x[j]需要的最小费用 
39         
40         int t=0;  //滚动数组的空间优化 
41         FOR(i,1,n) {
42             int k=0;
43             FOR(j,0,nx) {
44                 while(k<nx && x[k]<x[j]-d) k++;  //两者的取值必须不超过d 
45                 while(k+1<nx && x[k+1]<=x[j]+d && dp[t][k+1]<=dp[t][k])   //在 滑动窗口 中最小的  
46                   k++;
47                 //刷表法 更新 
48                 if(dp[t][k]==INF) dp[t^1][j]=INF;
49                 else dp[t^1][j]=dp[t][k]+abs(x[j]-h[i]);
50             }
51             t^=1;
52         }
53         
54         FOR(i,0,nx) if(x[i]==h[n-1])  //第N-1个数不能修改 
55           cout<<dp[t][i]<<"\n";
56         
57     }
58     return 0;
59 } 

 

你可能感兴趣的:(【暑假】[深入动态规划]UVa 12170 Easy Climb)