码迷,mamicode.com
首页 > 其他好文 > 详细

Dungeon Game 174

时间:2015-01-09 00:05:22      阅读:192      评论:0      收藏:0      [点我收藏+]

标签:

题目描述:

恶魔把公主关到了地牢(m x n 的grid)的右下角,骑士要从左上角的位置出发到达公主所在的位置解救公主

每个位置都有一个hp值,当骑士到达一个位置时,骑士的hp要加上该位置的hp(当该位置的hp小于0时,hp减少;当该位置的hp大于0时,hp增加)

骑士每次只能往下或者往右走

当骑士的hp值为0是,骑士立即die

计算骑士开始最少要有到少hp,才能到达右下角解救公主(开始位置和公主位置相应的hp也要计算)


 

题目分析:

求最优解,首先考虑dp

设置状态: d[i][j],表示从(i,j)位置到右下角开始需要最少的hp值

状态转移: d[i][j]=min(d[i+1][j],d[i][j+1])-dungeon[i][j]

从又下角到左上角递推

边界: 对最后一列和最后一行特殊处理

注意:d[i][j] <= 0是无意义的,当d[i][j]<=0时实际上表示的是在该位置,不需要额外的hp值,就可以到达右下角

但是要注意任何时候hp值不能小于等于0,这个时候d[i][j]应该设置为1,来表示不需要额外的hp值

所以对上面状态转移添加一点, 每次计算的d[i][j]之后,d[i][j]的实际值应该是 d[i][j] = d[i][j] > 0 ? d[i][j] : 1

 

结果:d[0][0]

 

 


优化

注意到上面状态转移方程,当前状态只用到了相邻一行的数据,这样可以利用滚动数组压缩空间为 O(n)

 

 

 


代码:

递推

 1 int live(int next,int dun){
 2     int ret=next-dun;
 3     if(ret<=0)ret=1;
 4     return ret;
 5 }
 6 
 7 int calculateMinimumHP(vector<vector<int> > &dungeon) {
 8         int lenx=dungeon.size();
 9         if(lenx<=0)return 0;
10         int leny=dungeon[0].size();
11         if(leny<=0)return 0;
12 
13         vector<int>d[2];
14 
15         int tag=0;
16         for(int j=0;j<leny;j++)d[0].push_back(0),d[1].push_back(0);
17 
18         d[tag][leny-1]=live(1,dungeon[lenx-1][leny-1]);
19         for(int j=leny-2;j>=0;j--)
20             d[tag][j]=live(d[tag][j+1],dungeon[lenx-1][j]);
21 
22         for(int i=lenx-2;i>=0;i--){
23             tag=1-tag;
24             d[tag][leny-1]=live(d[1-tag][leny-1],dungeon[i][leny-1]);
25 
26             for(int j=leny-2;j>=0;j--){
27                 d[tag][j]=live(min(d[1-tag][j],d[tag][j+1]),dungeon[i][j]);
28             }
29         }
30 
31         return d[tag][0];
32 }

 

 

 

Dungeon Game 174

标签:

原文地址:http://www.cnblogs.com/li-xingtao/p/4212029.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!