일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- Android
- ㅇ
- 심리여행
- static
- Navigation Component
- IMPLEMENT
- javap
- Interface
- 여행계획
- HelloWorld
- Transition
- 보안취약점
- 일상회피
- 버킷리스트
- abstract
- Recylcer
- Shared Elements
- throws
- 치유
- 여행
- 일상탈출
- 회피
- 취약점
- jvm
- extends
- bytecode 분석
- 보안
- bytecode
- 심리학
- opcode
- Today
- Total
패스트터틀
(Baekjoon) dp - (3) 외판원 순회 본문
https://www.acmicpc.net/problem/2098
2098번: 외판원 순회
첫째 줄에 도시의 수 N이 주어진다. (2 ≤ N ≤ 16) 다음 N개의 줄에는 비용 행렬이 주어진다. 각 행렬의 성분은 1,000,000 이하의 양의 정수이며, 갈 수 없는 경우는 0이 주어진다. W[i][j]는 도시 i에서 j로 가기 위한 비용을 나타낸다. 항상 순회할 수 있는 경우만 입력으로 주어진다.
www.acmicpc.net
우선 외판원 문제는 현재 나온 이론으로는 풀수없지만
그나마 가장 나은 방법으로 푸는것이 DP방법이다라는 사실을 알고있어야한다.
N! 를 n^2*2^n 으로 줄였다는 사실만 알자.
비트마스크 복습
dp[3][1011] 의 뜻은 3번째도시에서 2 번째도시까지 가는 최소한의 수
dp[2][111] 의 뜻은 2번째도시에서 3 번째도시까지 가는 최소한의 수
dp[1][11] 의 뜻은 1번째도시에서 2,3 or 3,2 번째도시까지 가는 최소한의 수
dp[0][1] 의 뜻은 0번째도시에서 2,3,4 or 2,4,3 or ... 번째 도시까지는 가는 최소한의 수
결국은 tsp를 재귀적으로 수행하면서
이러한과정중에
1. 최솟값을 dp에 넣고
2. 해당 dp가 다음번에도 있다면 재조사없이 그대로 갔다 쓰면서
동적으로 프로그래밍이 진행된다.
package dp;
import java.io.IOException;
import java.util.Scanner;
public class _2098 {
static int map[][] =new int[16][16];
static int dp[][] = new int[16][1<<16]; // [16][65536]
static int n,visited;
static int INF = Integer.MAX_VALUE - 1000000;
// visited : 내가 어디에 방문했는지 확인해보는 함수
static int tsp(int current, int visited){
if((visited == (1 << n) - 1 )){
if(map[current][0] == 0){
return INF;
}
return map[current][0];
}
if(dp[current][visited] != 0 ){
return dp[current][visited];
}
dp[current][visited] = INF;
for(int k = 0 ; k < n ; k++){
int next = 1 << k;
if(map[current][k] == 0 || (visited & next) > 0){
continue;
}
dp[current][visited] = Math.min(dp[current][visited], tsp(k, visited | next) + map[current][k]);
}
return dp[current][visited];
}
public static void main(String args[]) throws NumberFormatException, IOException {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
map[i][j] = Integer.parseInt(sc.next());
}
}
System.out.println(tsp(0,1));
}
}
이론만 가진상태에서 재귀함수를 사용하여 이걸 작성한 사람은 몇명이나 될까 생각이든다.
이런코드는 너무 이해가 안가서 공부하다보니까 어쩔수없이 외우는 코드같다.
그래도 재미있는 문제같다.
원본코드 : https://github.com/hotehrud/acmicpc/blob/master/algorithm/bitmask/2098.java
hotehrud/acmicpc
백준 알고리즘 문제. Contribute to hotehrud/acmicpc development by creating an account on GitHub.
github.com
코드제작자블로그 참고 : https://mygumi.tistory.com/361
비트마스크(BitMask) 는 무엇인가? :: 마이구미
이 글은 비트마스크(BitMask) 기법에 대해 다룬다. 특정 알고리즘이 아닌, bit 를 활용한 테크닉이라고 할 수 있다. bit 는 low level 이 아닌 경우에는 크게 비트를 다룰 일은 없어보이지만, 분명 이해가 필요한..
mygumi.tistory.com
백준문제풀이Github :
https://github.com/sdk0213/baekjoon-study
sdk0213/baekjoon-study
solve a baekjoon question. Contribute to sdk0213/baekjoon-study development by creating an account on GitHub.
github.com
'Algorithm > baekjoon' 카테고리의 다른 글
(Baekjoon) dp - (5) 타일 채우기 (0) | 2019.11.29 |
---|---|
(Baekjoon) dp - (4) 피보나치 (0) | 2019.11.28 |
(Baekjoon) etc.. - (1) 이진수 연산 (0) | 2019.11.21 |
(Baekjoon) dp - (2) 2×n 타일링 2 (0) | 2019.11.20 |
(Baekjoon) dp - (1) 2×n 타일링 (0) | 2019.11.20 |