티스토리 뷰
요약
- Bottom-Top 방식의 DP 적용
풀이과정
1. DP 배열 셋팅하기
표시를 쉽게 하기 위해 index 0은 사용하지 않고, 크기가 n+1,m+1인 배열을 선언한다.
그리고 0으로 초기화한다음, (1,1) 값만 1로 초기화한다.
int DP[n+1][m+1];
memset(DP,0,sizeof(DP));
DP[1][1] = 1;
2. 점화식 짜기
굉장히 직관적으로,
DP[i][j] = DP[i-1][j] + DP[i][j-1]
이라는 것을 알 수 있다. 물론 i,j의 범위를 고려해줘야 함.
3. puddle과
예제의 경우
0 | 0 | 0 | 0 | 0 |
0 | 1(집) | 0 | 0 | 0 |
0 | 0 | 0 | 0 | |
0 | 0 | 0 | 0 | 학교 |
이러한 상황인데, 만약, DP[i][j]가 puddle이라면 무조건 0으로 한다.
그렇게 하면, 나중에 점화식의 항으로 puddle이 들어가도, 0이 더해지기 때문에 따로 처리를 할 필요가 없다.
puddle 찾기는 algorithm의 find를 사용하였다.
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= m; j++)
{
vector<int> p = {j,i};
auto check = find(puddles.begin(), puddles.end(), p);
if(check != puddles.end()) //puddle
DP[i][j] = 0;
else if(i != 1 || j != 1)
DP[i][j] = (DP[i-1][j]+DP[i][j-1]) % DIV;
}
}
가장자리 부분도 둘러싼 부분이 모두 0으로 초기화되어있기 때문에 따로 if 범위를 나누지 않아도 된다.
코드
#include <bits/stdc++.h>
using namespace std;
#define DIV 1000000007
int solution(int m, int n, vector<vector<int>> puddles) {
int answer = 0;
int DP[n+1][m+1];
memset(DP,0,sizeof(DP));
DP[1][1] = 1;
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= m; j++)
{
vector<int> p = {j,i};
auto check = find(puddles.begin(), puddles.end(), p);
if(check != puddles.end()) //puddle
DP[i][j] = 0;
else if(i != 1 || j != 1)
DP[i][j] = (DP[i-1][j]+DP[i][j-1]) % DIV;
}
}
// for(int i = 1; i <= n; i++)
// {
// for(int j = 1; j <= m; j++)
// cout<<DP[i][j] << " ";
// cout << endl;
// }
answer = DP[n][m];
return answer;
}
'■ 알고리즘 > ◻ Programmers' 카테고리의 다른 글
[C++]이중우선순위큐 (0) | 2023.03.10 |
---|---|
[C++]디스크 컨트롤러 (0) | 2023.03.10 |
[C++]사칙연산 (0) | 2023.03.06 |
[C++]전력망을 둘로 나누기 (0) | 2023.03.01 |
[C++]주식 가격 (1) | 2023.01.06 |