標籤:
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_init34 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