*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;
}