일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 백트래킹
- 딥러닝
- 벤쿠버
- C++
- spring
- DP
- 머신러닝
- 다이나믹프로그래밍
- 모두를 위한 딥러닝
- 파이썬
- 릿코드
- 백준
- jvm
- Java
- leetcode
- Python
- STL
- 시애틀
- Spring Framework
- 프로그래밍언어론
- dfs
- 스타벅스
- 라인
- binary search
- 알고리즘
- C/C++
- 스프링 프레임워크
- 라인플러스
- 프로그래머스
- BFS
- Today
- Total
케이스윔의 개발 블로그
[백준][DP][Bitmasking] 2098번 외판원 순회 본문
문제
1부터 N까지 마을이 있을 때 마을을 순회할 수 있는 최소비용을 구하시오.
문제 출처: 백준 온라인저지(https://www.acmicpc.net/problem/2098)
풀이
이 문제는 Bitmask를 사용해서 dp를 만들어 나가보려고 푼 문제입니다. 여기서는 모든 마을을 순회해야할 때 방문한 마을을 표시하기 위해 Bitmask를 사용해보았습니다. dp를 통해 문제를 풀기 위해 배열이 필요하고, Bitmask를 사용한다면 어느 마을을 방문했는지 알 수 있으므로 dp배열에서 바로 사용을 할 수 있게 됩니다. 1번 마을을 방문했다면 1이고, 2번 마을을 방문했다면 10, 3번 마을을 방문했다면 100, 세 마을을 전부 방문했다면 111로 표현할 수 있습니다. 이 때 특정한 i번째의 마을을 방문했는지 알려면 visited & 1<<i 한 값이 1이 나올 것입니다. 이러한 연산을 응용해서 0번에서 순회를 시작하고(순회하는 것이니 어느마을에서 시작하더라도 싸이클 경로로 돌아오게 됩니다.) 0번으로 돌아오는 탐색을 합니다. 재귀적으로 방문하지 않은 마을들을 탐색하며 수행하며 만약 dp에 해당 값이 존재할 때에는 해당 값을 그대로 사용하고, visitied의 모든 비트가 1이 될 때 모든 마을을 탐색한 것이므로(visitied == (1<<N)-1) 해당 마을에서 0번 마을로 돌아갈 수 있는지 판단한 후에 값을 반환합니다. 재귀적으로 수행하며 가장 작은 반환값을 dp에 배열에 저장해주게 되면 모든 함수가 종료했을 때의 return 값은 최소 비용값이 됩니다. dp배열이 없다면(메모리제이션을 해주지 않으면) N=16임에도 불구하고 바로 시간초과가 나게 됩니다! Bimask를 활용한다는 것이 어떻게 보면 쉬운데 어떠한 값에 활용을 해줄지 캐치하는 것도 중요한 것 같습니다.
코드
https://github.com/kswim/Algorithm/blob/master/DP/2098.cpp
'Algorithm > Dynamic Programming' 카테고리의 다른 글
[백준][DP] 11055번 가장 큰 증가 부분 수열 (0) | 2019.01.31 |
---|---|
[백준][DP][Bitmasking] 2133번 타일채우기 (0) | 2019.01.30 |
[백준][DP] 1328번 고층빌딩 (0) | 2019.01.16 |
[백준][DP] 2167번 2차원 배열의 합 (0) | 2019.01.12 |
[백준][DP] 1912번 연속합 (0) | 2018.12.14 |