解题思路:

入坑思路:

起点和终点搞反,即把坐标(n-1,m-1)作为最终解出口。发现问题在求解的过程中总是要回溯到从(0,0)点到当前位置所经过路径上的血瓶计算,感觉问题始终在搞清和没搞清之间,非常痛苦。

正确思路:

是从(n-1,m-1)点到(0,0)点的求解,在一路走的过程当中只需要考虑当前存活下来的最优解即可。对于第n-1行,dp[n1][j]=max(dp[n1][j+1]v[n1][j],1)dp[n-1][j] = max(dp[n-1][j+1] - v[n-1][j],1),对于第m-1列,dp[i][m1]=max(dp[i+1][m1]v[i][m1],1)dp[i][m-1] = max(dp[i+1][m-1] - v[i][m-1],1),对于剩下的情况dp[i][j]=max(1,min(dp[i+1][j],dp[i][j+1])v[i][j])dp[i][j] = max(1, min(dp[i+1][j], dp[i][j+1]) - v[i][j]),最终dp[0][0]就是答案。 最终写了三种解题方案:递归,递推,在递推的基础上使用了空间优化

#include<bits/stdc++.h>
using namespace std;
int solve(int i, int j,int n, int m, vector<vector<int>> &v, vector<vector<int>> &dp){//递归
    if (dp[i][j] != -1) return dp[i][j];
    if (i == n-1 && j == m-1) dp[i][j] = max(1, 1-v[i][j]);
    else if(i == n-1) dp[i][j] = max(1, solve(i,j+1,n ,m, v, dp)- v[i][j]);
    else if(j == m-1) dp[i][j] = max(1, solve(i+1, j,n,m, v, dp) - v[i][j]);
    else dp[i][j] = max(1,min(solve(i+1, j,n,m, v, dp), solve(i, j+1,n,m, v, dp))- v[i][j]);
    return dp[i][j];
}
int solve2(vector<vector<int>> &v, vector<vector<int>> &dp, int n, int m){//递推
    dp[n-1][m-1] = max(1,1- v[n-1][m-1]);
    for(int i = n -2; i >= 0; -- i){
        dp[i][m-1] = max(dp[i+1][m-1]- v[i][m-1], 1);
    }
    for(int j = m -2; j >= 0; --j){
        dp[n-1][j] = max(dp[n-1][j+1] - v[n-1][j], 1);
    }
    for(int i = n-2; i >= 0; --i){
        for(int j = m-2; j >= 0; --j){
            dp[i][j] = max(1, min(dp[i+1][j], dp[i][j+1]) - v[i][j]);
        }
    }
    return dp[0][0];
}
int solve3(vector<vector<int>> &v, vector<int> &dp, int n, int m){//空间优化
    dp[m-1] = max(1,1 - v[n-1][m-1]);
    for(int i = m - 2; i >= 0; --i){
        dp[i] = max(1, dp[i+1] - v[n-1][i]);
    }
    for(int i = n-2; i >= 0; --i){
        dp[m-1] = max(1, dp[m-1] - v[i][m-1]); 
        for(int j = m-2; j >= 0; --j){
            dp[j] = max(1, min(dp[j+1], dp[j])- v[i][j]);
        }
    }
    return dp[0];
}
int main(){
    int n, m;
    cin>>n>>m;
    vector<vector<int>> v(n,vector<int>(m));
    vector<vector<int>> dp(n,vector<int>(m, -1));
    vector<int>dp2(m);
    for(int i = 0; i < n; ++i){
        for(int j = 0; j < m; ++j){
            cin>>v[i][j];
        }
    }
    // int ans = solve(0, 0,n,m ,v, dp);
    //int ans2 = solve2(v, dp, n, m);
    int ans3 = solve3(v, dp2, n, m);
    // cout<<ans<<endl;
    // cout<<ans2<<endl;
    cout<<ans3<<endl;
    return 0;
}