17069 c++ - 파이프 옮기기 2
2024. 10. 22. 11:20ㆍ🐣/BOJ
17070번. 파이프 옮기기 1 과 같은 문제이지만 N(3 ≤ N ≤ 32)의 범위가 굉장히 넓기 때문에 dp를 적용해야만 풀 수 있습니다. + int형을 return값으로 가지게 되면 오버플로우가 나므로 ll을 사용하여 풀어야 합니다.
완전탐색으로 풀었지만, 시간초과가 나게 되어서 dp에 대한 고민을 많이 해볼 수 있는 문제였습니다.
#include <iostream>
#include <vector>
using namespace std;
using ll = long long;
#define fastio ios::sync_with_stdio(0), cin.tie(0)
ll n;
ll dx[] = {1, 1, 0};
ll dy[] = {0, 1, 1};
ll dfs(ll y, ll x, ll dir, vector<vector<ll>> &b,
vector<vector<vector<ll>>> &v) {
if (y == n - 1 && x == n - 1) {
return 1;
}
if (v[y][x][dir] != -1) {
return v[y][x][dir];
}
v[y][x][dir] = 0;
for (ll i = 0; i < 3; i++) {
ll ny = y + dy[i];
ll nx = x + dx[i];
if (dir == 0 && i == 2) continue;
if (dir == 2 && i == 0) continue;
if (ny < 0 || nx < 0 || ny >= n || nx >= n || b[ny][nx] == 1) continue;
if (i == 1 && (b[ny - 1][nx] == 1 || b[ny][nx - 1] == 1)) continue;
v[y][x][dir] += dfs(ny, nx, i, b, v);
}
return v[y][x][dir];
}
int main() {
fastio;
cin >> n;
vector<vector<ll>> b(n, vector<ll>(n, 0));
// 메모이제이션 배열을 3차원으로 선언:
// [y][x][dir] (dir: 0=가로, 1=대각선, 2=세로)
vector<vector<vector<ll>>> v(n, vector<vector<ll>>(n, vector<ll>(3, -1)));
for (ll i = 0; i < n; i++) {
for (ll j = 0; j < n; j++) {
cin >> b[i][j];
}
}
if (b[0][1] == 1) {
cout << "0";
return 0;
}
cout << dfs(0, 1, 0, b, v);
return 0;
}
'🐣 > BOJ' 카테고리의 다른 글
26072 c++ - 곰곰이와 시소 (0) | 2024.10.23 |
---|---|
11052 c++ - 카드 구매하기 (0) | 2024.10.23 |
1644 c++ - 소수의 연속합 (0) | 2024.10.21 |
14003 swift - 가장 긴 증가하는 부분 수열 5 (0) | 2024.10.18 |
17088 c++ - 등차수열 변환 (0) | 2024.10.17 |