[补题]牛客练习56,迷宫【orz】

先上题:

QQ截图20200228235006

QQ截图20200228235025

思路:别被题目下到,其实就是一个dp,首先要对题目进行分析。

可得:

1. 它不会向左走, 因为向左走后,右边的格子就空了,那么就又要向右走,它就在这终老。

2. 不会向上走,因为向上走,就说明右边不通,就说明其当前一定是向右走一段后或者向下走过一段,如果向下走过一段,那么走上去没有意义。如果向右走过一段,可以先向左走。


综上所述:

       臭牛牛就只能向下和向右,最后才能逃出迷宫,然后上餐桌。

所以就可以的出递推公式。

dp(i,j)表示到(i,j)这个点需要添加的障碍数。


dp(i,j)​−>dp(i,j+1​)向右
dp(i,j)+(mp[i][j+1]==′0′)−>dp(i+1,j);向下

ac代码:


  1 #include <iostream>
  2 #include <algorithm>
  3 #include <cstring>
  4 #define INF 0x3f3f3f3f
  5 using namespace std;
  6 constexpr size_t maxn = 1005;
  7 string s[maxn];
  8 int dp[maxn][maxn];
  9 
 10 int main(){
 11 	int n, m;
 12 	cin >> n >> m;
 13 	for(int i = 0; i < n; ++ i)
 14 		cin >> s[i];
 15 	memset(dp, INF, sizeof(dp));
 16 
 17 	dp[0][0] = 0;
 18 	for(int i = 0; i < n; ++ i){
 19 		for(int j = 0; j < m; ++ j){
 20 			if(s[i][j] == '0'){
 21 				if(j < m-1 && s[i][j+1] == '0')//向右 
 22 					dp[i][j+1] = min(dp[i][j+1], dp[i][j]);
 23 				if(i < n-1 && s[i + 1][j] == '0'){
 24 					if(j == m - 1 || s[i][j+1] == '1')//如果右边直接是障碍物 
 25 						dp[i+1][j] = min(dp[i+1][j], dp[i][j]);
 26 					else
 27 						dp[i+1][j] = min(dp[i+1][j], dp[i][j] + 1);//添加障碍物将右边堵上。 
 28 				}
 29 			}
 30 		}
 31 	}
 32 	if(dp[n-1][m-1] == INF)puts("-1");
 33 	else
 34 		cout << dp[n-1][m-1] << endl;
 35 	return 0;
 36 }


追求吾之所爱
原文地址:https://www.cnblogs.com/rstz/p/14391077.html