BOJ#2631 줄세우기
* 문제
* 풀이
일단 [4, 1, 2, 3, 5]인 경우의 문제를 손으로 풀어봅시다.
거의 대부분 4를 3뒤로 옮겨서 한번만에 문제를 푸셨을 것입니다.
위 과정을 조금 더 상세하게 써보면
1. 수열에서 증가하는 가장 긴 부분 수열을 구하고 (이것들은 움직이지 않음)
[4, 1, 2, 3, 5]
나머지 숫자를 적절한 자리로 이동시키면 옮겨지는 아이의 수를 최소로 하면서 줄을 세울 수 있습니다.
[4, 1, 2, 3, 5] -> [1, 2, 3, 4, 5]
여기서 우리는 횟수만 구하면 되므로
전체 길이 - LIS(Longest Increasing Subsequence) 길이 = 아이의 최소 이동 횟수 = 원하는 답
저는 LIS Length를 구하는 과정에서 O(NlogN) 알고리즘을 사용하였습니다.
O(NlogN) 알고리즘은 아래 링크에서 참고해주세요
* 나의 코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
public class Main {
public static void main(String[] args) throws IOException {
// Input
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
int[] arr = new int[N];
for (int i = 0; i < N; i++) {
arr[i] = Integer.parseInt(br.readLine());
}
// Solve - LIS
int lisLength = getLISLength(arr);
System.out.println(N - lisLength);
}
static int getLISLength(int[] A) {
int length = A.length;
int[] tailTable = new int[length];
int lisLength = 0;
tailTable[lisLength++] = A[0];
for (int i = 1; i < length; i++) {
// 후보값이 tailTable의 첫번째 값보다 작은 경우
if (A[i] < tailTable[0]) {
tailTable[0] = A[i];
}
// 후보값이 tailTable의 마지막 값보다 작은 경우
else if (A[i] > tailTable[lisLength - 1]) {
tailTable[lisLength++] = A[i];
} else {
int idx = Arrays.binarySearch(tailTable, 0, lisLength, A[i]);
idx = idx < 0 ? -idx - 1 : idx;
tailTable[idx] = A[i];
}
}
return lisLength;
}
}
'Algorithm > DP' 카테고리의 다른 글
BOJ#2352 반도체 설계 (0) | 2017.10.09 |
---|---|
BOJ#1495 기타리스트 (0) | 2017.10.09 |
BOJ#2014 소수의 곱 (0) | 2017.09.27 |
BOJ#10164 격자상의 경로 (0) | 2017.09.26 |
BOJ#1904 01타일 (0) | 2017.09.25 |