先上题:
思路:别被题目下到,其实就是一个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 }