题解 | #龙与地下城游戏问题#
龙与地下城游戏问题
https://www.nowcoder.com/practice/c0ca4c9e65144af69ada03febaa0e33a
#include <cmath>
#include <iostream>
#include <vector>
using namespace std;
int main() {
int a, b;
while (cin >> a >> b) { // 注意 while 处理多个 case
vector<vector<int>> arr(a,vector<int>(b));
vector<vector<int>> dp(a+1,vector<int>(b+1,0x3f3f3f3f));
dp[a][b-1]=1;
dp[a-1][b]=1;
for(int i=0;i<a;i++)
for(int j=0;j<b;j++)
cin>>arr[i][j];
//正向考虑,很难考虑清楚有血瓶的情况给后面的影响。
//状态定义:
//反向考虑dp[i][j]:从[i,j]位置开始到终点所需的最少血量。
//状态转移:
//(1)[i,j]能够到达的只有两个位置向下走:[i+1,j],向右走[i,j+1];
//(2)我们需要保证从[i,j]到[i+1,j]血量>=1,那么至少需要的血量就是:dp[i+1][j]-arr[i][j];
//(3)我们需要保证从[i,j]到[i,j+1]血量>=1,那么至少需要的血量就是:dp[i][j+1]-arr[i][j];
//(4)上述两种结果要去较小的一个
//如果arr[i][j]>=0,即某一个位置有血瓶,上述计算dp[i+1][j]-arr[i][j]或dp[i][j+1]-arr[i][j]可能是一个负数,这就不符合游戏规则,最少需要的血量也要是1.
//所以最终结果要和1取max。
for(int i=a-1;i>=0;i--)
{
for(int j=b-1;j>=0;j--)
{
dp[i][j]=min(dp[i][j+1],dp[i+1][j])-arr[i][j];
dp[i][j]=max(1,dp[i][j]);
}
}
cout<<dp[0][0]<<endl;
}
}