-
Notifications
You must be signed in to change notification settings - Fork 1
17-froglike6 #66
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
17-froglike6 #66
Conversation
dohyeondol1
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
λΉνΈλ§μ€νΉμ μμ§ μ΅μνμ§κ° μμμ κ·Έλ°κ° νμ΄λ₯Ό μμλ΄λ μ½λλ₯Ό λ°λ‘ μ§κΈ°κ° μ΄λ ΅λ€μ...
κ·Έλ§μ λ λΉνΈλ§μ€ν¬ dpκ° μλλΌ λΉνΈλ§μ€ν¬λ§ μ¬μ©νμμ΅λλ€.
μ°Ύμ보λ μΈνμ μν(TSP)λ λΉνΈλ§μ€ν¬ DPλ₯Ό μ¬μ©νλ€κ³ νλλ°...
BFS μ°μ΅ λΏλ§ μλλΌ μμ©ν μ μλ λ΄μ©λ μμ΄μ λ°°μκ°κ² λ§μ λ¬Έμ λ€μ γ
γ
μ λ visited[y][x][mask] μνλ‘ νμμ μννμ΅λλ€.
λΉνΈλ§μ€ν¬λ μνκ΄λ¦¬ μ©λλ‘λ§ μ¬μ©νμ΄μ₯
μμ΄ν
κ°μκ° λ§μμ§λ€λ©΄ μ’ λΉν¨μ¨μ μΌμ μκ² λ€μ..
#include <iostream>
#include <queue>
#include <vector>
#include <tuple>
#include <algorithm>
using namespace std;
int N, M;
vector<string> house;
vector<pair<int, int>> items;
int dx[4] = {0, 1, 0, -1};
int dy[4] = {-1, 0, 1, 0};
int bfs(int sy, int sx, int ey, int ex, const vector<pair<int, int>>& items) {
int item_cnt = items.size();
vector<vector<int>> item_idx(M, vector<int>(N, -1));
for (int i = 0; i < item_cnt; ++i)
item_idx[items[i].first][items[i].second] = i;
vector<vector<vector<int>>> visited(M, vector<vector<int>>(N, vector<int>(1 << item_cnt, 0)));
queue<tuple<int, int, int, int>> q;
q.push({sy, sx, 0, 0});
visited[sy][sx][0] = 1;
while(!q.empty()) {
auto [y, x, mask, dist] = q.front();
q.pop();
if(y == ey && x == ex && mask == (1<<item_cnt)-1)
return dist;
for(int dir = 0; dir < 4; ++dir) {
int ny = y + dy[dir];
int nx = x + dx[dir];
if(ny < 0 || ny >= M || nx < 0 || nx >= N) continue;
if(house[ny][nx] == '#') continue;
int nmask = mask;
if(item_idx[ny][nx] != -1)
nmask |= (1 << item_idx[ny][nx]);
if(!visited[ny][nx][nmask]) {
visited[ny][nx][nmask] = 1;
q.push({ny, nx, nmask, dist + 1});
}
}
}
return -1;
}
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
cin >> N >> M;
house.resize(M);
for(int i = 0; i < M; ++i)
cin >> house[i];
int sy, sx, ey, ex;
items.clear();
for(int i = 0; i < M; ++i) {
for(int j = 0; j < N; ++j) {
if(house[i][j] == 'S') sy = i, sx = j;
if(house[i][j] == 'E') ey = i, ex = j;
if(house[i][j] == 'X') items.push_back({i, j});
}
}
int answer = bfs(sy, sx, ey, ex, items);
cout << answer << '\n';
return 0;
}|
μ λ λΉνΈλ§μ€νΉμ μ²μ μ ν΄λ³΄μμ μλ μ½λ 보면μ μ§λ³΄μμ΅λλ€..! bfsλ νλ λλ‘ νκ³ , #include <iostream>
#include <queue>
#include <vector>
using namespace std;
#define X first
#define Y second
#define INF 999999999
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};
vector<vector<int> > bfs(pair<int, int> sp, int m, int n, const vector<string> &map) {
vector<vector<int> > visited(m, vector<int>(n, -1));
queue<pair<int, int> > q;
q.push(sp);
visited[sp.X][sp.Y] = 0;
while (!q.empty()) {
pair<int, int> cur = q.front();
q.pop();
for (int i = 0; i < 4; i++) {
int nx = cur.X + dx[i];
int ny = cur.Y + dy[i];
if (nx < 0 || nx >= m || ny < 0 || ny >= n ||
map[nx][ny] == '#' || visited[nx][ny] != -1)
continue;
visited[nx][ny] = visited[cur.X][cur.Y] + 1;
q.push({nx, ny});
}
}
return visited;
}
int main() {
vector<pair<int, int> > x;
pair<int, int> s, e;
vector<pair<int, int> > p;
int n, m;
cin >> n >> m;
vector<string> map;
map.resize(m);
for (int i = 0; i < m; i++) {
cin >> map[i];
}
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (map[i][j] == 'S') {
s.X = i;
s.Y = j;
} else if (map[i][j] == 'E') {
e.X = i;
e.Y = j;
} else if (map[i][j] == 'X')
x.push_back(pair<int, int>(i, j));
}
}
p.push_back(s);
for (const auto &i: x)
p.push_back(i);
p.push_back(e);
int p_size = p.size();
vector<vector<int> > dist_matrix(p_size, vector<int>(p_size));
//bfs
for (int i = 0; i < p_size; i++) {
vector<vector<int> > dist = bfs(p[i], m, n, map);
for (int j = 0; j < p_size; j++) {
dist_matrix[i][j] = dist[p[j].X][p[j].Y];
}
}
int x_size = x.size();
if (x_size == 0) {
cout << dist_matrix[0][1] << endl;
return 0;
}
// dp
vector<vector<int> > dp(x_size, vector<int>(1 << x_size, INF));
for (int i = 0; i < x_size; i++) {
dp[i][1 << i] = dist_matrix[0][i + 1];
}
for (int mask = 1; mask < (1 << x_size); mask++) {
for (int i = 0; i < x_size; i++) {
if (mask & (1 << i)) {
for (int j = 0; j < x_size; j++) {
if (!(mask & (1 << j))) {
int cost = dist_matrix[i + 1][j + 1];
int next_mask = mask | (1 << j);
dp[j][next_mask] = min(dp[j][next_mask], dp[i][mask] + cost);
}
}
}
}
}
int min_total_dist = INF;
int all_mask = (1 << x_size) - 1;
for (int i = 0; i < x_size; i++) {
int cost_to_end = dist_matrix[i + 1][x_size + 1];
min_total_dist = min(min_total_dist, cost_to_end + dp[i][all_mask]);
}
cout << min_total_dist << endl;
return 0;
}
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
λΉνΈ λ§μ€νΉμΌλ‘ νμ¬ μ±κΈ΄ 물건λ€μ νννλ©΄, visited λ°©λ¬Έ μ²λ¦¬λ₯Ό μ½κ² ν΄λΌ μ μμ£ . μ½κ° μ΄λ €μ΄ κ·Έλν λ¬Έμ λ λΉνΈ λ§μ€νΉμ μλ μͺ½μΌλ‘ κΎΈμ€ν λμ€λ κ² κ°μμ :)
κ·Έλ°λ° μ£Όμ΄μ§λ μ λ ₯μ 보면 μ§ ν¬κΈ°λ μμ΄ν κ°μμ μ΅λκ°μ΄ μκΈ° λλ¬Έμ μ‘°κΈ λΉν¨μ¨μ μΈ νμ΄λ λ κ² κ°λλΌκ΅¬μ. μ λ μλμ κ°μ΄ νμ΄λ΄€μ΅λλ€.
- μμ μ§μ Sμ λμ°© μ§μ Eλ κ³ μ
- S, E μ¬μ΄μ λ°©λ¬Έν΄μΌ ν μμ΄ν μμλ₯Ό "μμ΄"μ μ΄μ©ν΄ λͺ¨λ κ²½μ°μ μλ₯Ό νμΈ
- S ->
$X_1$ μ λν΄ BFS /$X_1$ ->$X_2$ μ λν΄ BFS / ... /$X_k$ -> Eμ λν΄ BFSλ₯Ό μν, κ°κ°μ BFSλ‘λΆν° λ°νλ μ΅λ¨ κ²½λ‘μ ν©μ κ³μ° - μ΄ μ΅λ¨ κ²½λ‘ ν© μ€ κ°μ₯ μμ κ°μ μΆλ ₯
μμ€ μ½λ
#include <bits/stdc++.h>
using namespace std;
using Vector2 = pair<int32_t, int32_t>;
enum : uint8_t {
START = 'S',
END = 'E',
ITEM = 'X',
EMPTY = '.',
WALL = '#',
};
const vector<Vector2> OFFSET {
{-1, 0},
{0, 1},
{1, 0},
{0, -1}
};
int32_t N, M;
vector<vector<int32_t>> gVisited;
Vector2 s, e;
vector<Vector2> items;
inline bool isOutOfBound(int i, int j) {
return i < 0 || i >= N || j < 0 || j >= M;
}
int32_t BFS(Vector2 src, Vector2 dst) {
queue<Vector2> q;
q.emplace(src);
vector<vector<int32_t>> visited = gVisited;
visited[src.first][src.second] = 0;
int32_t move = 0;
while(!q.empty()) {
const auto cur = q.front();
q.pop();
if(cur == dst) {
move = visited[dst.first][dst.second];
break;
}
const auto& [i, j] = cur;
for(const auto& [di, dj] : OFFSET) {
int32_t ni = i + di, nj = j + dj;
if(isOutOfBound(ni, nj) || visited[ni][nj] > -1) {
continue;
}
visited[ni][nj] = visited[i][j] + 1;
q.emplace(ni, nj);
}
}
return move;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> M >> N;
gVisited.assign(N, vector<int32_t>(M, -1));
for(int32_t i = 0; i < N; ++i) {
for(int32_t j = 0; j < M; ++j) {
uint8_t val; cin >> val;
if(val == WALL) {
gVisited[i][j] = 0;
continue;
}
if(val == START) {
s = {i, j};
} else if(val == END) {
e = {i, j};
} else if(val == ITEM) {
items.emplace_back(i, j);
}
}
}
if(items.empty()) {
cout << BFS(s, e);
return 0;
}
sort(items.begin(), items.end());
int32_t ans = 1e9;
do
{
int32_t move = BFS(s, items.front());
for(int32_t i = 0; i < items.size() - 1; ++i) {
move += BFS(items[i], items[i + 1]);
}
move += BFS(items.back(), e);
ans = min(ans, move);
} while(next_permutation(items.begin(), items.end()));
cout << ans;
return 0;
}κ·Έλ°λ° λ€μ μκ°ν΄λ³΄λ μμ μ§μ , λμ°© μ§μ , 물건 μ§μ λ³ κ±°λ¦¬λ κ³ μ λμ΄ μλλΌκ΅¬μ. λͺ¨λ κ²½μ°μ μ λ§λ€ BFSλ₯Ό νΈμΆν΄μ 거리λ₯Ό λ€μ κ³μ°ν νμλ μμ΄, μ΅μ΄ 1νμ νν΄ λͺ¨λ μμΉμ λν μ΅λ¨ κ²½λ‘ κ°μ 미리 κ³μ°ν΄λμΌλ©΄ μμ΄μ μ΄μ©ν΄ κ²½μ°μ μλ₯Ό λ°μ§ λ μΊμ±λ 거리κ°μ μ΄μ©νλ©΄ λ λΉ λ₯΄κ² κ³μ°ν μ μκ² λλΌκ΅¬μ.
C++
#include <bits/stdc++.h>
using namespace std;
using Vector2 = pair<int, int>;
enum : uint8_t {
START = 'S',
END = 'E',
ITEM = 'X',
EMPTY = '.',
WALL = '#',
};
const vector<Vector2> OFFSET = {
{-1, 0}, {0, 1}, {1, 0}, {0, -1}
};
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int M, N;
cin >> M >> N;
vector<vector<char>> house(N, vector<char>(M));
Vector2 s, e;
deque<Vector2> points;
for (int i = 0; i < N; ++i) {
for (int j = 0; j < M; ++j) {
char c;
cin >> c;
house[i][j] = c;
if(c == START) {
s = {i, j};
} else if(c == END) {
e = {i, j};
} else if(c == ITEM) {
points.emplace_back(i, j);
}
}
}
points.emplace_front(s);
points.emplace_back(e);
auto isOutOfBound = [N, M](int i, int j) {
return i < 0 || i >= N || j < 0 || j >= M;
};
auto BFS = [&house, N, M, &isOutOfBound](const Vector2 &src) {
queue<Vector2> q;
vector<vector<int>> d(N, vector<int>(M, -1));
q.push(src);
d[src.first][src.second] = 0;
while (!q.empty()) {
auto [i, j] = q.front();
q.pop();
for (const auto& [di, dj] : OFFSET) {
int ni = i + di, nj = j + dj;
if(isOutOfBound(ni, nj) || house[ni][nj] == WALL || d[ni][nj] > -1) {
continue;
}
d[ni][nj] = d[i][j] + 1;
q.emplace(ni, nj);
}
}
return d;
};
const int numPoints = points.size();
const int INF = 1e9;
vector<vector<int>> dist(numPoints, vector<int>(numPoints, INF));
for(int u = 0; u < numPoints; ++u) {
auto distFromSrc = BFS(points[u]); // uλ² μ§μ (μΆλ°/λμ°©/λ¬Όκ±΄λ€ μ€ 1κ°)μΌλ‘λΆν° λλ¨Έμ§ λͺ¨λ μ§μ κΉμ§μ κ±°λ¦¬κ° μ μ₯λ 2μ°¨μ λ°°μ΄
for(int v = 0; v < numPoints; ++v) {
const auto& [vi, vj] = points[v];
if(u != v && distFromSrc[vi][vj] > -1) {
dist[u][v] = distFromSrc[vi][vj]; // u-> v μ΅λ¨ 거리 μ μ₯
}
}
}
int ans = INF;
if (points.size() == 2) { // κ°μ Έκ°μΌ ν λ¬Όκ±΄μ΄ μλ€λ©΄
ans = dist[0][1]; // pointsλ [S, E]λ§ μ‘΄μ¬
} else { // λ¬Όκ±΄μ΄ μλ€λ©΄
vector<int> perm;
for(int i = 1; i <= numPoints - 2; ++i) { // S, [X1, X2, ..., Xi], K μ€ λ¬Όκ±΄λ€μ λν μΈλ±μ€ μΆμΆ
perm.emplace_back(i);
}
sort(perm.begin(), perm.end());
do {
int sum = dist[0][perm[0]]; // S -> 물건 1λ²
for (int i = 0; i + 1 < perm.size(); ++i) { // 물건 1λ² -> 2λ², 2λ² -> 3λ², ...
sum += dist[perm[i]][perm[i + 1]];
}
sum += dist[perm.back()][numPoints - 1]; // λ§μ§λ§ 물건 -> E
ans = min(ans, sum); // 거리 ν© μ€ μ΅μκ° μΊμ±
} while (next_permutation(perm.begin(), perm.end())); // 물건 μΈλ±μ€λ€μ μμ΄λ‘ λͺ¨λ κ²½μ°μ μ νμΈ
}
cout << ans;
return 0;
}python
def solution(N, M, house):
s, e = None, None
p = []
for i in range(N):
for j, c in enumerate(house[i]):
if c == 'S':
s = (i, j)
elif c == 'E':
e = (i, j)
elif c == 'X':
p.append((i, j))
p = [s] + p + [e]
pn = len(p)
OFFSET = ((-1, 0), (0, 1), (1, 0), (0, -1))
def bfs(src):
q = deque([src])
d = [[-1] * M for _ in range(N)]
d[src[0]][src[1]] = 0
while q:
i, j = q.popleft()
for di, dj in OFFSET:
ni, nj = i + di, j + dj
if (0 <= ni < N and 0 <= nj < M) and house[ni][nj] != '#' and d[ni][nj] == -1:
d[ni][nj] = d[i][j] + 1
q.append((ni, nj))
return d
INF = 10**9
pn = len(p)
dist = [[INF] * pn for _ in range(pn)]
for u, src in enumerate(p):
d = bfs(p[u])
for v, dst in enumerate(p):
vi, vj = dst
if u != v and d[vi][vj] > -1:
dist[u][v] = d[vi][vj]
ans = INF
items = list(range(1, pn - 1))
if not items:
ans = dist[0][1]
else:
for perm in permutations(items):
total = dist[0][perm[0]]
for a, b in zip(perm, perm[1:]):
total += dist[a][b]
total += dist[perm[-1]][pn - 1]
ans = min(ans, total)
return ans
def main(input):
M, N = map(int, input().split())
house = tuple(tuple(input().rstrip()) for _ in range(N))
print(solution(N, M, house))
if __name__ == "__main__":
from collections import deque
from itertools import permutations
main(open(0).readline)
hadongun
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
λΉνΈλ§μ€νΉμ΄ μ΅μμΉ μμ κ·Έλ₯ visited 리μ€νΈλ₯Ό μ΄μ©ν΄ λμ ν΄λ³΄μμ΅λλ€
μ΄μ μ λ΄€λ λ¬Έμ λ€μ 거리 ν
μ΄λΈμ΄ μ£Όμ΄μ‘λ κ² κ°μλ°
거리 ν
μ΄λΈμ μ§μ ꡬν΄μΌ νλ κ²½μ°λ μ²μ 보λ κ² κ°μμ!
κ·Έλν νμμ μ‘°κΈ μκ² λλ€κ³ μκ°νμ§λ§ λ μ΄μ¬ν ν΄μΌκ² μ΄λ₯..
Details
from collections import deque
import sys
input = sys.stdin.readline
def bfs(sx, sy, board, N, M):
visited = [[-1]*N for _ in range(M)]
q = deque()
q.append((sx, sy))
visited[sy][sx] = 0
while q:
x, y = q.popleft()
for dx, dy in [(0,1), (1,0), (0,-1), (-1,0)]:
nx, ny = x + dx, y + dy
if 0 <= nx < N and 0 <= ny < M and board[ny][nx] != '#' and visited[ny][nx] == -1:
visited[ny][nx] = visited[y][x] + 1
q.append((nx, ny))
return visited
N, M = map(int, input().split())
board = [list(input().strip()) for _ in range(M)]
points = []
for i in range(M):
for j in range(N):
if board[i][j] == 'S':
points.insert(0, (j, i))
elif board[i][j] == 'E':
points.append((j, i))
elif board[i][j] == 'X':
points.append((j, i))
k = len(points)
dist_table = [[-1]*k for _ in range(k)]
for i in range(k):
visited = bfs(points[i][0], points[i][1], board, N, M)
for j in range(k):
x, y = points[j]
dist_table[i][j] = visited[y][x]
min_total = sys.maxsize
visited = [False] * k
def dfs(now, depth, total):
global min_total
if depth == k - 2:
d = dist_table[now][k-1]
if d != -1:
min_total = min(min_total, total + d)
return
for nxt in range(1, k - 1):
if not visited[nxt]:
d = dist_table[now][nxt]
if d == -1:
continue
visited[nxt] = True
dfs(nxt, depth + 1, total + d)
visited[nxt] = False
dfs(0, 0, 0)
print(min_total)
π λ¬Έμ λ§ν¬
μλ§λ€μ°μ°
βοΈ μμλ μκ°
1μκ°
β¨ μλ μ½λ
μλμ½λ(μ½κ° μ΄λ €μΈ κ² κ°μ μ£Όμλ λ¬μμ΄μ)
μ΄ λ¬Έμ λ λ¨μν BFS λ¬Έμ μ λΉμ·νμ§λ§, μ½κ° λ€λ₯Έ λ¬Έμ μ λλ€. BFSλ‘ λͺ¨λ κ²½λ‘μ κΈΈμ΄λ₯Ό ꡬνκ³ , λΉνΈλ§μ€ν¬ DPλ₯Ό ν΅ν΄ κ°μ₯ μ κ² μμ§μ΄λ κ²½λ‘λ₯Ό μ°Ύμ΅λλ€. λΉνΈλ§μ€ν¬λ #24 μ μ€λͺ λμ΄ μμ΅λλ€ γ γ . μ΄λ₯Ό νμ©ν DPλΌκ³ μκ°νμλ©΄ λκ² μ΅λλ€.
격μ μμ μΆλ°μ μμ μμνμ¬ λͺ¨λ μμ΄ν μ μ»κ³ , μΆκ΅¬λ‘ μ΄λν΄μΌ ν©λλ€. λ¨Όμ μ λ ₯μμ 격μλ₯Ό λ°κ³ , νμν λ Έλλ₯Ό
nodeμ μ μ₯ν©λλ€(S, λͺ¨λ E, X).κ·Έλ° λ€μ
nodeμ λͺ¨λ λ Έλμ λν΄ BFSλ₯Ό λλ € λͺ¨λ λ Έλ κ° μ΅λ¨ 거리 νλ ¬distλ₯Ό λ§λλλ€.μ΄μ λΉνΈλ§μ€ν¬ DPλ‘ λμ΄κ°κ² μ΅λλ€.
maskλkλΉνΈ μ§ν©μΌλ‘, κ° λΉνΈκ° 1μ΄λ©΄ ν΄λΉ μμ΄ν μ νλνλ€κ³ μ€μ νμ΅λλ€. κ·Έλ° λ€μdp[mask][i]μλ€κ°, maskλ μνμμnode[i]μ λμ°©ν μ΅μ 거리λ₯Ό μ μ₯νμ΅λλ€. λͺ¨λ μμ΄ν μ μννκ³ μΆκ΅¬λ‘ λκ°, λ΅μ λμΆν μ μμμ΅λλ€.π μλ‘κ² μκ²λ λ΄μ©
λΉνΈλ§μ€ν¬ DPλ₯Ό μκ² λμμ΅λλ€. μ΄ λ¬Έμ μμλ μμ΄ν μ μκ° μμμ λ€μ΅μ€νΈλΌλ₯Ό μ¬μ©νμ§ μμλλ°, μλ‘ μκ² λ λΉνΈλ§μ€ν¬ DPλ₯Ό μ¬μ©νλ©΄μ λΉκ΅μ λ λΉ λ₯΄κ² κ³μ°ν μ μμμ΅λλ€.