주어진 m * n
각 셀 중 하나 인 그리드, 0
(빈) 또는 1
(장애물). 한 단계에서, 당신은에서와 빈 셀에 왼쪽 또는 위, 아래, 오른쪽으로 이동할 수 있습니다.
왼쪽 상단에서 걷는 단계의 최소 수를 돌려 (0, 0)
오른쪽 하단 모서리에 (m-1, n-1)
가장에서 제거 할 수 주어진 k
장애물을. 그것은 할 수없는 경우 같은 거리의 수익을 찾을 수 -1.
예 1 :
입력 :
그리드 =
[0,0,0],
[1,1,0],
[0,0,0],
[0,1,1],
[0,0,0],
K = 1 개
출력 6
명 :
장애물을 제거하지 않고 최단 경로 (10) 인
위치에서 하나 개의 장애물 제거 (3,2)와 최단 경로 6. 이러한 경로이다 (0,0) -> (0,1) -> (0,2) -> (1,2) -> (2,2) -> (3,2) -> (4,2)
.
예 2 :
입력 :
그리드 =
[0,1,1],
[1,1,1],
[1,0,0],
K = 1 개
출력 : -1
설명 :
우리는을 찾기 위해 두 개 이상의 장애물을 제거하기 위해 필요 산책.
제약 :
grid.length == m
grid[0].length == n
1 <= m, n <= 40
1 <= k <= m*n
grid[i][j] == 0 or 1
grid[0][0] == grid[m-1][n-1] == 0
문제의 의미 매트릭스 주어지는, Q [0,0]에서, 수직 및 수평으로 이동 될 수있는 이동 [N-1, m-1]와 방법에 k 번째 장애물의 대부분을 제거하는 단계의 최소 개수.
해결 방법 : 분명히 동적 프로그래밍 문제. DFS는 동적 프로그래밍 저장된 결과가 중복 계산을 피하기 위해 계산 된 사용하여 반복 간단한 계산을 많이 가지고 있어요.
int dirs[4][2] = {-1,0, 0,1,1,0,0,-1}; int dp[41][41][1700]; bool flag[41][41]; class Solution { public: vector<vector<int>> _grid; bool inside(int x, int y){ if(x>=0 && x<_grid.size() && y>=0 &&y<_grid[0].size()) return true; return false; } int shortestPath(vector<vector<int>>& grid, int k) { _grid = grid; memset(dp, -1, sizeof(dp)); memset(flag, 0 ,sizeof(flag)); int ret = dfs(0, 0, k); return ret>=INT_MAX/2 ? -1 : ret; } int dfs(int x, int y, int k){ if(k<0) return INT_MAX/2; if(dp[x][y][k] != -1) return dp[x][y][k]; if(x==_grid.size()-1 && y==_grid[0].size()-1) return dp[x][y][k] = 0; int ret = INT_MAX/2; for(int i=0; i<4; i++){ int xx = x+dirs[i][0]; int yy = y+dirs[i][1]; if(inside(xx, yy) && !flag[xx][yy]){ flag[xx][yy] = true; int temp = INT_MAX/2; if(_grid[xx][yy]) temp = dfs(xx, yy, k-1); else temp = dfs(xx, yy, k); ret = min(ret, 1+temp); flag[xx][yy] = false; } } return dp[x][y][k] = ret; } };