题解 | #龙与地下城游戏问题# 终点反推 + 内存优化
龙与地下城游戏问题
https://www.nowcoder.com/practice/c0ca4c9e65144af69ada03febaa0e33a
应该是目前最最优的解,没想出来从起点推到终点的规划方法。如果能够从起点起推,那就可以用滚动数组存储输入数据,进一步优化内存。
下面这篇解是从起点开始推的,能通过用例测试,但没有考虑极端情况,即最大收益路线和最低血量路线可能并不重合,可是他的解法里,每一步最低血量的决策跟随了最大收益。
https://blog.nowcoder.net/n/405e917d5f6f423cb1f5999f43a4c75a?f=comment
#include <climits> #include <iostream> #include <vector> using namespace std; template<typename T> int main() { int n, m,i, j; cin >> n >> m; vector<vector<int>> gameMap(n, vector<int>(m)); m--; n--; for(i=0;i<=n;++i){ for(j=0;j<=m;++j){ cin>>gameMap[i][j]; } } vector<vector<int>> dp(2, vector<int>(gameMap[0].size(), 0)); int fromRight, fromBottom, cur,prev; cur = gameMap.size()-1)%2; dp[cur][gameMap[0].size()-1] = gameMap[n][m]>0?1:1-gameMap[n][m]; //算出dp矩阵,每格代表进入这一格时的最低血量 for (i = n; i>=0; --i) { for (j = i!=n ? m : m-1; j >=0 ; --j) { cur=i%2; prev=(i+1)%2; fromBottom=(i!=n?max( dp[prev][j]-gameMap[i][j],1):INT_MAX) ; fromRight=(j!=m? max(dp[cur][j+1]-gameMap[i][j],1):INT_MAX) ; dp[cur][j]=min(fromBottom,fromRight); } } cout<<dp[cur][0] << endl; return 0; }