龙与地下城游戏

/********************************************************************************************

 *description:龙与地下城游戏

 *            给定一个二维数组map,表示一张地图,

 *            骑士从左上角出发,每次只能向右或向下走,最后到达右下角见到公主

 *            map每个位置数字,正数代表加血,负数代表有怪兽减血,骑士血量不能少于1

 *            为保证骑士能见到公主,初始血量最少是多少?

 *******************************************************************************************/

#include<iostream>
#include<vector>
using namespace std;
//方法:时间复杂度O(M*N),空间复杂度O(M*N)
//经典动态规划问题,创建与map同大的二维数组dp[M][N]
//dp[i][j]代表骑士走上[i,j]位置且从该位置走到右下角需要的最低血量,最终需要的结果是dp[0][0]
//dp[M-1][N-1],骑士走上最终位置需要的最低血量=
//                                      1,当map[M-1][N-1]>=0
//                                      1-map[M-1][N-1],当map[M-1][N-1]<0
//dp[M-1][j]最后一行=max(1, dp[M-1][j+1]-map[M-1][j]
//dp[i][N-1]最后一列=max(1, dp[i+1][N-1]-map[i][N-1]
//dp[i][j]:取两项最小值,从右往左从下往上遍历
//          1.max(1,dp[i-1][j]-map[i][j])
//          2.max(1,dp[i][j-1]-max[i][j])
//得到dp之后,右下角元素即为结果。
int minBlood(vector<vector<int>> map)
{
    int M = map.size();
    int N = map[0].size();

    vector<vector<int>> dp(M, N);
    if (map[M-1][N-1] >= 0)
        dp[M-1][N-1] = 1;
    else
        dp[M-1][N-1] = 1-map[M-1][N-1];

    for (int j = N-2; j >= 0; j--)
        dp[M-1][j] = dp[M-1][j+1] - map[M-1][j] > 1 ? dp[M-1][j+1] - map[M-1][j] : 1;
    for (int i = M-2; i >= 0; i--)
        dp[i][N-1] = dp[i+1][N-1] - map[i][N-1] > 1 ? dp[i+1][N-1] - map[i][N-1] : 1;

    for (int i = M-2; i >= 0; i--)
    {
        for (int j = N-2; j >= 0; j--)
        {
            int val1 = dp[i+1][j]-map[i][j] > 1 ? dp[i+1][j]-map[i][j] : 1;
            int val2 = dp[i][j+1]-map[i][j] > 1 ? dp[i][j+1]-map[i][j] : 1;
            dp[i][j] = val1 > val2 ? val2 : val1;
        }
    }
    return dp[0][0];
}


int main_11()
{
    vector<vector<int>> map;

    int l1[3] ={ -2, -3, 3};
    vector<int> line1(l1, l1+3);

    int l2[3] ={ -5, -10, 1};
    vector<int> line2(l2, l2+3);

    int l3[3] ={ 0, 30, -5};
    vector<int> line3(l3, l3+3);

    map.push_back(line1);
    map.push_back(line2);
    map.push_back(line3);

    cout << minBlood(map);

    return 0;
}
点赞