๋ฌธ์ : https://school.programmers.co.kr/learn/courses/30/lessons/214290
๊ฒฝ์ฌ๊ฐ 1๋ฒ ๋ฐ๋ณต๋๋ ๊ฒฝ๋ก์ ์๋ฅผ ๊ตฌํด์ k๋ฒ ๋ฐ๋ณต๋๋ ๊ฒฝ๋ก์ ์๋ฅผ ๊ตฌํ๋ฉด ๋๋ ๋ฌธ์ ๋ค.
1. ๊ฒฝ์ฌ๊ฐ 1๋ฒ ๋ฐ๋ณต๋๋ ๊ฒฝ๋ก์ ์ ๊ตฌํ๊ธฐ
ํ ์นธ์์ ๋ค๋ฅธ ์นธ์ผ๋ก ํด์ง ๊ฑด๋๊ฐ๋ ๊ฒ์ hop
์ด๋ผ๊ณ ์นญํ๋ค.
dp[startX][startY][endX][endY][hop]: (startX, startY)์์ ์์ํ์ฌ (endX, endY)๊น์ง ์ด๋ํ์ ๋, d[0]~d[hop]๊น์ง์ ๊ฒฝ์ฌ๋ฅผ ๋ง์กฑํ๋ ๊ฒฝ๋ก์ ์
๋ฌธ์ ์์ ์ฃผ์ด์ง ์์ ๋ฅผ ์๋ก ๋ค์ด๋ณด์. d = [1, -2, -1, 0, 2]์ด๋ค.
(1,1)๋ถํฐ (2, 3)๊น์ง๋ d[0]๋ถํฐ d[2]๊น์ง์ ๊ฒฝ์ฌ [-1, -2, -1]๋ฅผ ๋ง์กฑํ๋ ๊ฒฝ๋ก์ ์๊ฐ 1๊ฐ์ด๋ค.
๋ฐ๋ผ์ dp[1][1][2][3][2] = 1์ด ๋๋ค.
// long[][][][][] route;
// int[][][][][] dp;
// int N = grid.length, M = grid[0].length, K=1_000_000_007;
// int[] dx = {-1, 1, 0, 0}, dy = {0, 0, -1, 1};
void findRoute(int x, int y, int hop, int[][] grid, int[] d) {
for (int k=0; k<4; k++) {
int nx = x+dx[k];
int ny = y+dy[k];
if(nx<0 || ny<0 || nx>=N || ny>=M) continue;
if(grid[nx][ny]-grid[x][y] != d[hop]) continue;
if(hop==0) {
dp[x][y][nx][ny][hop] = 1;
} else {
for (int i=0; i<N; i++) {
for (int j=0; j<M; j++) {
dp[i][j][nx][ny][hop] += dp[i][j][x][y][hop-1];
dp[i][j][nx][ny][hop] %= K;
}
}
}
}
}
for (int hop=0; hop<d.length; hop++) {
// ๋ชจ๋ ์์์ ์ ๋ํ์ฌ ๋ฐ๋ณต
for (int i=0; i<N; i++) {
for (int j=0; j<M; j++) {
findRoute(i, j, hop, grid, d);
}
}
}
for (int startX=0; startX<N; startX++) {
for (int startY=0; startY<M; startY++) {
for (int endX=0; endX<N; endX++) {
for (int endY=0; endY<M; endY++) {
route[startX][startY][endX][endY][0] = dp[startX][startY][endX][endY][d.length-1];
}
}
}
}
dp๋ฅผ ์ด์ฉํ์ฌ ์ฒ์์๋ ๊ฒฝ์ฌ 1๊ฐ(d[0])๋ง ๋ง์กฑํ๋ ๊ฒฝ๋ก์ ์๋ฅผ ์ฐพ๊ณ ,
๊ทธ ๋ค์์๋ 2๊ฐ(d[0], d[1])๋ฅผ ๋ง์กฑํ๋ ๊ฒฝ๋ก์ ์๋ฅผ ์ฐพ๊ณ ,
์ด๋ฅผ ๋ฐ๋ณตํ๋ค๊ฐ ๋ง์ง๋ง์ ๋ชจ๋ ๊ฒฝ์ฌ๋ฅผ ๋ง์กฑํ๋ ๊ฒฝ๋ก์ ์๋ฅผ ์ฐพ์ผ๋ฉด ๋๋ค.
(BFS๋ก ํ๋ฉด ๋ฉ๋ชจ๋ฆฌ ์ด๊ณผ๊ฐ ๋ฐ์ํ๋ค.)
2. ๊ฒฝ์ฌ๊ฐ k๋ฒ ๋ฐ๋ณต๋๋ ๊ฒฝ๋ก์ ์ ๊ตฌํ๊ธฐ
๊ฒฝ์ฌ๊ฐ 1๋ฒ ๋ฐ๋ณต๋๋ ๊ฒฝ๋ก์ ์๋ฅผ ๊ตฌํ๋ค. ๊ฒฝ๋ก๊ฐ 2๋ฒ ๋ฐ๋ณต๋๋ ๊ฒฝ์ฐ์ ์๋ ์๋์ ๊ฐ๋ค.
(์์์ ~๋์ฐฉ์ ๊ฒฝ์ฌ 2๋ฒ ๋ฐ๋ณต๋๋ ๊ฒฝ๋ก์ ์) = (์์์ ~๊ฒฝ์ ์ง ๊ฒฝ์ฌ 1๋ฒ ๋ฐ๋ณต๋๋ ๊ฒฝ๋ก์ ์) * (๊ฒฝ์ ์ง~๋์ฐฉ์ ๊ฒฝ์ฌ 1๋ฒ ๋ฐ๋ณต๋๋ ๊ฒฝ๋ก์ ์)
(์์์ ~๋์ฐฉ์ ๊ฒฝ์ฌ 3๋ฒ ๋ฐ๋ณต) = (์์์ ~๊ฒฝ์ ์ง ๊ฒฝ์ฌ 2๋ฒ ๋ฐ๋ณต) * (๊ฒฝ์ ์ง~๋์ฐฉ์ ๊ฒฝ์ฌ 1๋ฒ ๋ฐ๋ณต) ์ด๋ฏ๋ก
k = l+m์ผ ๋, (์์์ ~๋์ฐฉ์ ๊ฒฝ์ฌ k๋ฒ ๋ฐ๋ณต) = (์์์ ~๊ฒฝ์ ์ง ๊ฒฝ์ฌ l๋ฒ ๋ฐ๋ณต) * (๊ฒฝ์ ์ง~๋์ฐฉ์ ๊ฒฝ์ฌ m๋ฒ ๋ฐ๋ณต)์ด ๋๋ค.
์ด์ฒ๋ผ k๋ฒ์ ๋ฐ๋ณตํ๋ฉด ๋ต์ ๊ตฌํ ์ ์๊ฒ ์ง๋ง, k์ ์ต๋๊ฐ = 10^9 ์ด๋ฏ๋ก ์๊ฐ์ด๊ณผ๊ฐ ๋ ํ๋ฅ ์ด ๋งค์ฐ ๋๋ค.
์นธ์ ๊ฐ์๊ฐ ์ต๋ 64๊ฐ์ด๋ฏ๋ก, (์์์ , ๊ฒฝ์ ์ง, ๋์ฐฉ์ ) ์์ ๊ตฌํ๋ ๊ฒ๋ง์ผ๋ก๋ 64*64*64 โ 10^6์ด๊ธฐ ๋๋ฌธ์ด๋ค.
๊ทธ๋ ๋ค๋ฉด ์ด๋ป๊ฒ ํด์ผ ํ ๊น?
(์์์ ~๋์ฐฉ์ ๊ฒฝ์ฌ 1๋ฒ ๋ฐ๋ณต)์ ์ด์ฉํด
(์์์ ~๋์ฐฉ์ ๊ฒฝ์ฌ 2๋ฒ ๋ฐ๋ณต)
(์์์ ~๋์ฐฉ์ ๊ฒฝ์ฌ 4๋ฒ ๋ฐ๋ณต)
.
.
.
(์์์ ~๋์ฐฉ์ ๊ฒฝ์ฌ 2^n๋ฒ ๋ฐ๋ณต) ์ ๊ตฌํ๋ค.
for (int repeat = 1; repeat<str.length(); repeat++) {
for (int start=0; start<N*M; start++) {
int startX = start/M;
int startY = start%M;
for (int end=0; end<N*M; end++) {
int endX = end/M;
int endY = end%M;
for (int stopOver=0; stopOver<N*M; stopOver++) {
int stopOverX = stopOver/M;
int stopOverY = stopOver%M;
route[startX][startY][endX][endY][repeat] += (route[startX][startY][stopOverX][stopOverY][repeat-1]%K * route[stopOverX][stopOverY][endX][endY][repeat-1]%K)%K;
route[startX][startY][endX][endY][repeat]%=K;
}
}
}
}
๊ทธ๋ฆฌ๊ณ k๋ฅผ ์ด์ง์๋ก ํํํ ๋ค, ๊ธฐ์กด์ ๊ตฌํด๋ 2^n๋ฒ ๋ฐ๋ณต์ ์ด์ฉํด k๋ฒ ๋ฐ๋ณต๋๋ ๊ฒฝ๋ก์ ์๋ฅผ ๊ตฌํ๋ฉด ๋๋ค.
์๋ฅผ ๋ค์ด, k = 12 = 8 + 4๋ผ๊ณ ํ๋ฉด
(๋์ฐฉ์ ๊น์ง ๊ฒฝ์ฌ๊ฐ 12๋ฒ ๋ฐ๋ณต๋๋ ๊ฒฝ๋ก์ ์) = (์์์ ๊น์ง ๊ฒฝ๋ก 8๋ฒ ๋ฐ๋ณต) * (์์์ ~๋์ฐฉ์ ๊น์ง ๊ฒฝ๋ก 4๋ฒ ๋ฐ๋ณต)์ด ๋๋ค.
// StringBuilder sb = new StringBuilder(Integer.toBinaryString(k));
// String str = sb.reverse().toString();
// answer[i][j]: ํ์ฌ๊น์ง (i,j)๋ฅผ ๋์ฐฉ์ ์ผ๋ก ์ผ๋ ๊ฒฝ๋ก์ ์
void countRoute(String str) {
for (int idx=0; idx<str.length(); idx++) {
if(str.charAt(idx)=='0') continue;
long[][] newAnswer = new long[N][M];
for (int start=0; start<N*M; start++) {
int startX = start/M;
int startY = start%M;
for (int end=0; end<N*M; end++) {
int endX = end/M;
int endY = end%M;
newAnswer[endX][endY] += (answer[startX][startY]%K) * (route[startX][startY][endX][endY][idx]%K);
newAnswer[endX][endY]%=K;
}
}
answer = newAnswer;
}
}
3. ์ ๋ต ์ธ๊ธฐ
๊ทธ๋ฆฌ๊ณ ๋ง์ง๋ง์ผ๋ก ๋ชจ๋ ์ ์ ๋ํ์ฌ, ํด๋น ์ ์ ๋์ฐฉ์ ์ผ๋ก ํ๋ ๊ฒฝ๋ก์ ์๋ฅผ ์ธ์ด์ฃผ๋ฉด ๋๋ค.
long ans = 0;
for (int endX=0; endX<N; endX++) {
for (int endY=0; endY<M; endY++) {
ans += (answer[endX][endY]%K);
ans %= K;
}
}
์ ์ฒด ์ฝ๋
import java.util.Arrays;
public class Programmers_๊ฒฝ์ฌ๋ก์๊ฐ์ {
long[][][][][] route;
int[][][][][] dp;
long[][] answer;
int N, M, K=1_000_000_007;
int[] dx = {-1, 1, 0, 0}, dy = {0, 0, -1, 1};
public int solution(int[][] grid, int[] d, int k) {
N = grid.length;
M = grid[0].length;
StringBuilder sb = new StringBuilder(Integer.toBinaryString(k));
String str = sb.reverse().toString();
route = new long[N][M][N][M][str.length()];
dp = new int[N][M][N][M][d.length];
answer = new long[N][M];
for (int i=0; i<N; i++) {
Arrays.fill(answer[i], 1);
}
for (int hop=0; hop<d.length; hop++) {
for (int i=0; i<N; i++) {
for (int j=0; j<M; j++) {
findRoute(i, j, hop, grid, d);
}
}
}
for (int startX=0; startX<N; startX++) {
for (int startY=0; startY<M; startY++) {
for (int endX=0; endX<N; endX++) {
for (int endY=0; endY<M; endY++) {
route[startX][startY][endX][endY][0] = dp[startX][startY][endX][endY][d.length-1];
}
}
}
}
for (int repeat = 1; repeat<str.length(); repeat++) {
for (int start=0; start<N*M; start++) {
int startX = start/M;
int startY = start%M;
for (int end=0; end<N*M; end++) {
int endX = end/M;
int endY = end%M;
for (int stopOver=0; stopOver<N*M; stopOver++) {
int stopOverX = stopOver/M;
int stopOverY = stopOver%M;
route[startX][startY][endX][endY][repeat] += (route[startX][startY][stopOverX][stopOverY][repeat-1]%K * route[stopOverX][stopOverY][endX][endY][repeat-1]%K)%K;
route[startX][startY][endX][endY][repeat]%=K;
}
}
}
}
countRoute(str);
long ans = 0;
for (int endX=0; endX<N; endX++) {
for (int endY=0; endY<M; endY++) {
ans += (answer[endX][endY]%K);
ans %= K;
}
}
return (int) ans;
}
void findRoute(int x, int y, int hop, int[][] grid, int[] d) {
for (int k=0; k<4; k++) {
int nx = x+dx[k];
int ny = y+dy[k];
if(nx<0 || ny<0 || nx>=N || ny>=M) continue;
if(grid[nx][ny]-grid[x][y] != d[hop]) continue;
if(hop==0) {
dp[x][y][nx][ny][hop] = 1;
} else {
for (int i=0; i<N; i++) {
for (int j=0; j<M; j++) {
dp[i][j][nx][ny][hop] += dp[i][j][x][y][hop-1];
dp[i][j][nx][ny][hop] %= K;
}
}
}
}
}
void countRoute(String str) {
for (int idx=0; idx<str.length(); idx++) {
if(str.charAt(idx)=='0') continue;
long[][] newAnswer = new long[N][M];
for (int start=0; start<N*M; start++) {
int startX = start/M;
int startY = start%M;
for (int end=0; end<N*M; end++) {
int endX = end/M;
int endY = end%M;
newAnswer[endX][endY] += (answer[startX][startY]%K) * (route[startX][startY][endX][endY][idx]%K);
newAnswer[endX][endY]%=K;
}
}
answer = newAnswer;
}
}
}
'๐๐ฅ๐ ๐จ๐ซ๐ข๐ญ๐ก๐ฆ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[ํ๋ก๊ทธ๋๋จธ์ค] ๋๋์ง ์๊ฐ์ด๊ณผ ํด๊ฒฐ ํ๊ธฐ (0) | 2024.02.21 |
---|---|
[ํ๋ก๊ทธ๋๋จธ์ค] ๋ฑ์ฐ์ฝ์ค ์ ํ๊ธฐ (1) | 2023.11.08 |
[ํ๋ก๊ทธ๋๋จธ์ค] ํ ๋ณํฉ (0) | 2023.09.10 |
[ํ๋ก๊ทธ๋๋จธ์ค] ์๊ณผ ๋๋ (0) | 2023.09.07 |
[๋ฐฑ์ค 5052] ์ ํ๋ฒํธ ๋ชฉ๋ก (0) | 2023.09.04 |