题意大概是给定M×N的棋盘格,从左上到右下,只能向右或者向下走,每走一步需要加上棋盘格子内的数值(有正有负)。
需要随时保证当前的数值>=1。问初始需要最少的值是多少?
思路:
动态规划。用dp[i][j]代表当前最大的数值。首先求出dp[m][n],得出到达右下角的最优值。
然后再回溯求出从左上角到右下角的路径。然后为了随时保证路径上的值>=1,找到路径上最小的值。
如果最小值>=1,那么初始只需要0即可满足条件。如果最小值<0,假如为-5,那么初始值必须为6,才能随时保证路径上的值>=1。
测试用例
m =2,n=3
-2 -3 3
-5 -10 1
输出 6.
int mininit() { int m,n; cin>>m>>n; vector<vector<int>>board(m+1,vector<int>(n+1,0)); vector<vector<int>> dp(m+1,vector<int>(n+1,0)); for(int i=0;i<m;i++) { for(int j =0;j<n;j++) { cin>>board[i+1][j+1]; } } dp[1][1]= board[1][1]; for(int i=2;i<=n;i++)dp[1][i] = dp[1][i-1]+board[1][i]; for(int i=2;i<=m;i++)dp[i][1] = dp[i-1][1]+board[i][1]; for(int i =2;i<=m;i++) { for(int j=2;j<=n;j++) { dp[i][j] = max(dp[i-1][j],dp[i][j-1])+board[i][j]; } } int minv = dp[m][n]; while(m!=1|| n!=1) //回溯找到路径 { if( (dp[m][n]-board[m][n]) == dp[m-1][n]) m = m-1;//当前m n是由上一行m-1 n得来的 否则是由左边m n-1得来的 else n = n-1; minv = min(minv,dp[m][n]);//记录路径上最小值 // cout<<m<<" "<<n<<endl; } if(minv>=1)return 0; return 1-minv; }