๋ฌธ์ :
programmers.co.kr/learn/courses/30/lessons/67259
๋ถ์ :
์ด ๋ฌธ์ ๋ ๋ฐฑ์ค์์ ํ์๋ ๋ด๋ฆฌ๋ง๊ธธ ๋ฌธ์ ์ ๋น์ทํ๊ฒ dp + dfs์ ์กฐํฉ๋ฌธ์ ์๋ค.
์ฐ์ ๋ฏธ๋ฆฌ ๊ณ ํ์ง๋ง TC 24๋ฒ๋ง ํต๊ณผํ์ง ๋ชปํ๋ค ใ
๋ค๋ง ์ํ, ์ข์ฐ๋ฅผ ์ด๋ํ ๋ ๋น์ฉ์ด ๋ฌ๋ฆฌ ๋ค์๋๋ฐ ์ด ์ ์์ ์ด๋ป๊ฒ ํด๊ฒฐํ๋ฉด ์ข์์ง ๋ชฐ๋ผ ํ๋์ฝ๋ฉ ํ๋๋ฐ ์๊ฐ์ ์ฉ์ฉ๋งธ๋ค.
๊ทธ๋ฌ๋ ์ค ๋ค๋ฅธ ๋ถ์ ์์ด๋์ด๋ฅผ ์ฐธ๊ณ ํด ์ ์ด๋ ๊ฒ ์ ๊ทผํ๋ ์ข์ ๋ฐฉ๋ฒ์ด ..! ๋ฅผ ๋ฐ๊ฒฌํ๋ค.
1. ๊ฐ ๋น์ฉ ๊ณ์ฐํ๊ธฐ(์ง์ ๋๋ก, ์ฝ๋ ๋๋ก ?)
์ง์ ๋๋ก, ์ฝ๋ ๋๋ก ๋น์ฉ
์ํ์ข์ฐ๋ฅผ ๋๊ธฐ ์ํด bfs์
int dx[] = { 0, 0, 1, -1 }; //up down left right
int dy[] = { 1, -1, 0, 0 };
์ ์ธ๋ฑ์ค๋ฅผ ์ฐธ๊ณ ํด ๋ ๊ฒ์ด๋ค.
์ธ๋ฑ์ค i๊ฐ
์ํ์ผ๋ 0, 1
์ข์ฐ์ผ๋ 3, 2
์ฝ๋ ๋๋ก๋ ์ํ -> ์ข์ฐ ๋๋ ์ข์ฐ -> ์ํ๋ก ์ฆ ์ธ๋ฑ์ค๊ฐ 0, 1 -> 2, 3์ผ๋ก ๋๋ 2, 3 -> 0, 1๋ก ๋ณํํ ๋ ๋๊ณ + ์ง์ ๋๋ก = 600 ์์ ๋น์ฉ์ด ๋ ๊ฒ์ด๋ค.
์ฒ์ bfs๋ฅผ ๋ ์ ๋น์ฉ์ -1๋ก ์ด๊ธฐํ ํด์ฃผ์๋ค.
๊ทธ๋ฆฌ๊ณ before๊ณผ now ์ธ๋ฑ์ค์ ๊ฐ ๋ณํ๋ฅผ ๋น๊ตํด ์ ์ ํ ๋น์ฉ์ ๊ณ์ฐํด ์ค๋ค ..!
2. DP ์ต์ ๋น์ฉ
๊ณ์ฐ๋ ๋น์ฉ์ ๋ํด
dp [x][y]: (x, y)๊น์ง ๋๋ก ๊ฑด์คํ๋๋ฐ ๋๋ ์ต์ ๋น์ฉ
์ ์ต์ ๋น์ฉ์ด ์์ผ๋ฉด ๊ฐฑ์ ์์ผ์ฃผ๊ณ ๋ค์ ๋ฐฉ๋ฌธ์ ์ฌ๊ท๋ก ์ด๋ํ๋ค.
์ด๋ ๋ ์ฃผ์ํด์ผ ํ ์ ์ visit๋ฅผ ํตํด ๋ฐฉ๋ฌธํ ์ฅ์๋ ๊ฐ์ง ์๊ฒ ํ๋ ๊ฒ์ธ๋ฐ bfs๊ฐ ๋๋๋ฉด ๋์์ค๋ ๊ณผ์ ์์ visit๋ฅผ false๋ก ๋ง๋ค์ด
๋ค์ for๋ฌธ์ ๋๊ณ ๊ทธ์ ๋ํ ๋ ์ต์ ์ ๊ฐ์ด ์๋ค๋ฉด dp์ ์ต์์ ๊ฐ์ผ๋ก ๋ค์ ๊ณ์ฐ๋์ด ์ ์ฅ๋๊ฒ ํ๋ ์ ์ ๊ฐ๊ณผํด์ ์๋๋ค.
c++ ์ฝ๋ :
//
// [KAKAO] 2020_trackBuild.cpp
// SOMA๐ฉ๐ป๐ป
//
// Created by JoSoJeong on 2021/05/07.
//
#include <stdio.h>
#include <iostream>
#include <vector>
#include <string.h>
#include <queue>
using namespace std;
int nextPay = 0;
//
//vector<vector<int>> board = {{0,0,0,0,0,0,0,1},{0,0,0,0,0,0,0,0},{0,0,0,0,0,1,0,0},{0,0,0,0,1,0,0,0},{0,0,0,1,0,0,0,1},{0,0,1,0,0,0,1,0},{0,1,0,0,0,1,0,0},{1,0,0,0,0,0,0,0}};
vector<vector<int>> board = {{0,0,1},{1,0,1},{1,0,0}};
int size = (int) board.size();
bool visit[26][26];
int dp[26][26];
int answer = 0;
int dx[] = { 0, 0, 1, -1 }; //up down left right
int dy[] = { 1, -1, 0, 0 };
//dp ๋ฐฐ์ด ํ์ธ์ฉ
void print_dp(){
for(int i =0; i < board.size(); i++){
for(int j = 0; j < board.size(); j++){
cout << dp[i][j] << " ";
}
cout << '\n';
}
cout << '\n';
}
int calculate_pay(int before, int now){
if(before == -1){
return 100;
}else if((before == 2|| before == 3) &&(now == 0|| now == 1)){
return 600;
}else if((before == 0|| before == 1) &&(now == 2|| now == 3)){
return 600;
}
return 100;
}
void make_bfs(int x, int y, int dir, int pay){
for(int i = 0; i < 4 ; i++){
int nx = x + dx[i];
int ny = y + dy[i];
if(nx < 0 || ny < 0|| nx >= size || ny >= size) continue;
if(board[nx][ny] == 1 || visit[nx][ny] == true) continue;
pay = calculate_pay(dir, i);
if(dp[nx][ny] < dp[x][y] + pay){
continue;
}
dp[nx][ny] = dp[x][y] + pay;
visit[nx][ny] = true;
make_bfs(nx, ny, i, pay);
//print_dp();
visit[nx][ny] = false;
// false๊ฐ ๋๊ณ ๋์์ค๋ ๊ณผ์ ์์ ๋ค์ for๋ฌธ์ ๋๊ณ ๊ทธ์ ๋ํ ๋ ์ต์ ์ ๊ฐ์ด ์๋ค๋ฉด dp์ ์ต์์ ๊ฐ์ผ๋ก ๋ค์ ๊ณ์ฐ๋์ด ์ ์ฅ๋๋ค.
}
}
int main(){
// ์ด๊ธฐํ
memset(visit, false, sizeof(visit));
for(int i =0; i < board.size(); i++){
for(int j = 0; j < board.size(); j++){
dp[i][j] = 10000000;
}
}
dp[0][0] = 0;
make_bfs(0, 0, -1, 0);
cout << dp[size -1][size -1] << '\n';
return 0;
}
๊ฒฐ๊ณผ :
๋ญ ๋นผ๋จน์ ๊ฒ์ผ๊น๋ .. ์์ง์ ์ ๋ชจ๋ฅด๊ฒ ๋ค ใ
์๋ ค์ฃผ์๋ฉด ๊ฐ์ฌํ๊ฒ ์ต๋๋ค .. ๐ฅบ๐ฅบ
๋๊ธ