ZOJ3555 Ice Climber(dp)

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

Ice Climber


Time Limit: 2 Seconds      Memory Limit: 32768 KB


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-1th block or to the right, the i+1th block as you like, but not the ith 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 0th block or the w+1th 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 1st block from the nth block, or get to the nth block from the 1st block.

And just like the picture below, the 2nd floor‘s floor is the 1st 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 nth floor.(Any block on the nth 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 t1t2, andt3.(0<=t1,t2,t3<=100)

Then the 2n 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 nth floor downto the 1st floor, that is, the first line of this map describes what is on the nth floor, and the second line of this map describes the number of the pieces of each block of nth floor, or the n-1th floor‘s ceil.

Output

In each case, output one line with an integer representing the minimum time little Eskimo can get to the nth floor. If there is no way to get to the nth 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 }
时间: 2024-12-23 16:38:13

ZOJ3555 Ice Climber(dp)的相关文章

URAL1965:Pear Trees(DP)

Vova was walking along one of Shenzhen streets when he noticed young pear trees, growing along the pavement. Each tree had a plaque attached to it containing some number. Vova walked around all n trees and found out that the numbers on the plaques ar

最短路(数据处理):HDU 5817 Ice Walls

Have you ever played DOTA? If so, you may know the hero, Invoker. As one of the few intelligence carries, Invoker has 10 powerful abilities. One of them is the Ice Wall: Invoker generates a wall of solid ice directly in front of him, and the bitter c

BZOJ_1021_[SHOI2008]_Debt循环的债务_(DP)

描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1021 三个人相互欠钱,给出他们每个人各种面额的钞票各有多少张,求最少需要传递多少张钞票才能把账还清. 分析 用\(f[i][j][k]\)表示用过前\(i\)种钞票后,A有\(j\)元,B有\(k\)元所需要的步数. 然后DP就好了. 1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn=1000+5,IN

对ICE的期待

2017年,共享经济持续成为大众关注的焦点,从共享单车.共享雨伞.共享充电宝,到共享电动车.共享汽车.共享床位,甚至连女友都拿来共享了.戴上"共享"高帽的创业项目一茬接一茬地冒出来,正如收割的韭菜,最开始两茬是最嫩的,接下来生长出来的则会让人觉得食之无味又弃之可惜.对于投资人如此,对于用户们来说有何尝不是呢? 让我们盘点下近一年出现过的"共享"明星们,对于它们,死亡还是生存?这是个问题. 据统计,2016年中国的共享经济市场规模接近4万亿元:2017年,共享系宣告进

HDU 5542 The Battle of Chibi dp+树状数组

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5542 题意:给你n个数,求其中上升子序列长度为m的个数 可以考虑用dp[i][j]表示以a[i]结尾的长度为j的上升子序列有多少 裸的dp是o(n2m) 所以需要优化 我们可以发现dp的第3维是找比它小的数,那么就可以用树状数组来找 这样就可以降低复杂度 #include<iostream> #include<cstdio> #include<cstring> #include

hdu 1207 汉诺塔II (DP+递推)

汉诺塔II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4529    Accepted Submission(s): 2231 Problem Description 经典的汉诺塔问题经常作为一个递归的经典例题存在.可能有人并不知道汉诺塔问题的典故.汉诺塔来源于印度传说的一个故事,上帝创造世界时作了三根金刚石柱子,在一根柱子上从下往

POJ - 3186 Treats for the Cows (区间DP)

题目链接:http://poj.org/problem?id=3186 题意:给定一组序列,取n次,每次可以取序列最前面的数或最后面的数,第n次出来就乘n,然后求和的最大值. 题解:用dp[i][j]表示i~j区间和的最大值,然后根据这个状态可以从删前和删后转移过来,推出状态转移方程: dp[i][j]=max(dp[i+1][j]+value[i]*k,dp[i][j-1]+value[j]*k) 1 #include <iostream> 2 #include <algorithm&

51Nod 1009 数字1的个数 | 数位DP

题意: 小于等于n的所有数中1的出现次数 分析: 数位DP 预处理dp[i][j]存 从1~以j开头的i位数中有几个1,那么转移方程为: if(j == 1) dp[i][j] = dp[i-1][9]*2+pow(10,i-1);else dp[i][j] = dp[i-1][9]+dp[i][j-1]; 然后注意下对于每个询问统计的时候如果当前位为1需要额外加上他后面所有位数的个数,就是n%pow(10,i-1); 这样总复杂度log(n)*10 #include <bits/stdc++.

HDU 3555 Bomb (数位DP)

数位dp,主要用来解决统计满足某类特殊关系或有某些特点的区间内的数的个数,它是按位来进行计数统计的,可以保存子状态,速度较快.数位dp做多了后,套路基本上都差不多,关键把要保存的状态给抽象出来,保存下来. 简介: 顾名思义,所谓的数位DP就是按照数字的个,十,百,千--位数进行的DP.数位DP的题目有着非常明显的性质: 询问[l,r]的区间内,有多少的数字满足某个性质 做法根据前缀和的思想,求出[0,l-1]和[0,r]中满足性质的数的个数,然后相减即可. 算法核心: 关于数位DP,貌似写法还是