## ZOJ3555 Ice Climber(dp)

**转载请注明出处： http://www.cnblogs.com/fraud/ ——by fraud**

Maybe many one have played or at least heard of *The Family Computer(FC)*. And this problem is mainly about a classical game named *"Ice Climber"*

In this game, our little Eskimo wants to climb higher and catch the big bird at last. In the climbing, little Eskimo may be faced with many troubles, like enemy or wall.

The game field made up with several floors and floors are seperated by many pieces of bricks. The number of pieces between different floors and different positions are different. There may also be enimies and walls on these bricks. By jumping up Eskimo can decrease the number of pieces on the ceiling of his position or even jump to another floor.

Each time Eskimo can choose on of the following steps:

- Move left or right one block as long as the block is empty and the block has supporting pieces of bricks, using
`t1`time.(That is, there will not be an enemy or a wall on the block and the block has at least one bricks) - Jump up and destroy one piece of brick of the ceil just above little Eskimo or Jump up to an upper floor if all bricks on the ceiling of his current position have been cleared. If he jumps to the next floor he can choose to land on either the left or the right adjacent position as long as there are no enimies or walls on them (Of course there must also be at least a supporting brick at that position). Both kind of jumping takes
`t2`time. - Knock off one little enemy just next to little Eskimo in
`t3`time, and the enemy will disappear.

Each block has several pieces. And only if the number of the pieces of the block is 0 can little Eskimo jump up through it to the next floor. Sometimes Eskimo may clear all the bricks of ceiling of a position where there is an enemy standing on it, in these cases this unlucky enemy will be cleared at once. If on the next floor, above one block there is a wall, then Eskimo can never jump up through this block no matter how much pieces it has even zero. If little Eskimo jumped up to the next floor successfully, for instance through the ith position, he can choose to land on either to the left, the i-1_{th} block or to the right, the i+1_{th} block as you like, but not the i_{th} block itself. And you can never jump over the enemy or the wall or the zero pieces blocks.

And in the whole process, little Eskimo can not land on to the side, that is, he can not land on to the 0_{th} block or the w+1_{th} block. Also, he cannot land on to where there are only zero pieces blocks or blocks with an enemy or blocks with a wall. And while moving, he cannot get to the 1_{st} block from the n_{th} block, or get to the n_{th} block from the 1_{st} block.

And just like the picture below, the 2_{nd} floor's floor is the 1_{st} floor's ceil:

Now, we have `n` floors, and each floor has the same width of `w` blocks, but the number of the pieces of each block can be different. Thus, we can get a map of these floors. Little Eskimo starts from **the leftest block on the first floor**, unlike the picture above, and we want to use the minimum time to get to the n_{th} floor.(**Any block on the n _{th} is all right**)

#### Input

The input contains multiple cases.

In each case, the first line contains two integers represents `n` and `w`.(1<=`n`<=2000 , 1<=`w`<=100)

The second line contains three integers represents `t1`, `t2`, and`t3`.(0<=`t1`,`t2`,`t3`<=100)

Then the 2`n` lines, the odd lines contains `w` characters, describing what is on the floor: '#' represents the enemy, which we assume **does not move**, '|' represents wall, and '0' represents the block is empty. While the even lines contains `w` digits from '0' to '9' representing the number of the pieces of each block.

**[Notice]**: the map inputs from the `n`_{th} floor downto the 1_{st} floor, that is, the first line of this map describes what is on the `n`_{th} floor, and the second line of this map describes the number of the pieces of each block of `n`_{th} floor, or the `n-1`_{th} floor's ceil.

#### Output

In each case, output one line with an integer representing the minimum time little Eskimo can get to the `n`_{th} floor. If there is no way to get to the `n`_{th} floor, output -1.

#### Sample Input

This sample input just describe the picture above.

5 22 1 2 3 0000000000000000000000 2222212222122222221222 0000000000000000000000 2122222122222221112222 000000000000000000000# 2222212221222222222111 0000000000000000000000 2222222222112222222221 0000#00000000000000000 1111111111111111111111

#### Sample Output

23

**题目很长，大致规则和游戏中差不多，从最下面一层的左边出发，不能越过墙‘|’，打掉一个怪的时间是t3,水平走一步的时间是t1，往左上或者右上跳，并且打掉上方一个砖块的时间是t2，不能碰到怪，不能踩在空中，另外还有一些细节，然后要求到达最上面一层最少需要多少时间**

**dp[i][j] 表示走到第i层最少花费时间，这个点可以从下面一层任意一个可达的地方转移过来，所以复杂度就是n*w*w**

1 /** 2 * code generated by JHelper 3 * More info: https://github.com/AlexeyDmitriev/JHelper 4 * @author xyiyy @https://github.com/xyiyy 5 */ 6 7 #include <iostream> 8 #include <fstream> 9 10 //##################### 11 //Author:fraud 12 //Blog: http://www.cnblogs.com/fraud/ 13 //##################### 14 //#pragma comment(linker, "/STACK:102400000,102400000") 15 #include <iostream> 16 #include <sstream> 17 #include <ios> 18 #include <iomanip> 19 #include <functional> 20 #include <algorithm> 21 #include <vector> 22 #include <string> 23 #include <list> 24 #include <queue> 25 #include <deque> 26 #include <stack> 27 #include <set> 28 #include <map> 29 #include <cstdio> 30 #include <cstdlib> 31 #include <cmath> 32 #include <cstring> 33 #include <climits> 34 #include <cctype> 35 36 using namespace std; 37 #define INF 0x3FFFFFFF 38 #define rep(X, N) for(int X=0;X<N;X++) 39 #define rep2(X, L, R) for(int X=L;X<=R;X++) 40 #define dep(X, R, L) for(int X=R;X>=L;X--) 41 42 char f[2010][110], s[2010][110]; 43 int dp[2010][110]; 44 45 class TaskG { 46 public: 47 void solve(std::istream &in, std::ostream &out) { 48 int n, w; 49 while (in >> n >> w) { 50 int t1, t2, t3; 51 in >> t1 >> t2 >> t3; 52 rep2(i, 1, n) { 53 in >> f[i] + 1; 54 in >> s[i] + 1; 55 } 56 rep(i, n + 10) { 57 rep(j, w + 10)dp[i][j] = INF; 58 } 59 dp[n][1] = 0; 60 int num = 0; 61 if (f[n][1] == '|' || s[n][1] == '0')dp[n][1] = INF; 62 rep2(i, 2, w) { 63 if (f[n][i] == '|' || s[n][i] == '0')break; 64 if (f[n][i] == '#')num += t3; 65 num += t1; 66 dp[n][i] = dp[n][1] + num; 67 } 68 dep(i, n - 1, 1) { 69 rep2(j, 1, w) { 70 if (f[i][j] == '|' || s[i][j] == '0')continue; 71 num = 0; 72 if (f[i][j] == '#')num += t3; 73 bool ok = 0; 74 dep(k, j - 1, 1) { 75 if (f[i][k] == '|')break; 76 if (s[i][k] == '0')ok = 1; 77 if (f[i][k + 1] != '#') dp[i][j] = min(dp[i][j], dp[i + 1][k] + num + (s[i][k] - '0' + 1) * t2); 78 if (f[i][k] == '#')num += t3; 79 num += t1; 80 if (ok)break; 81 } 82 ok = 0; 83 num = 0; 84 if (f[i][j] == '#')num += t3; 85 rep2(k, j + 1, w) { 86 if (f[i][k] == '|')break; 87 if (s[i][k] == '0')ok = 1; 88 if (f[i][k - 1] != '#')dp[i][j] = min(dp[i][j], dp[i + 1][k] + num + (s[i][k] - '0' + 1) * t2); 89 if (f[i][k] == '#')num += t3; 90 num += t1; 91 if (ok)break; 92 } 93 } 94 } 95 int ans = INF; 96 rep2(i, 1, w)ans = min(ans, dp[1][i]); 97 if (ans == INF)ans = -1; 98 out << ans << endl; 99 } 100 } 101 }; 102 103 int main() { 104 std::ios::sync_with_stdio(false); 105 std::cin.tie(0); 106 TaskG solver; 107 std::istream &in(std::cin); 108 std::ostream &out(std::cout); 109 solver.solve(in, out); 110 return 0; 111 }