Algorithm/DP

BOJ#2631 줄세우기

밤이2209 2017. 9. 28. 15:53

BOJ#2631 줄세우기


* 문제



* 풀이

일단 [4, 1, 2, 3, 5]인 경우의 문제를 손으로 풀어봅시다.
거의 대부분 4를 3뒤로 옮겨서 한번만에 문제를 푸셨을 것입니다.

위 과정을 조금 더 상세하게 써보면

1. 수열에서 증가하는 가장 긴 부분 수열을 구하고 (이것들은 움직이지 않음)
[4, 1, 2, 3, 5]

나머지 숫자를 적절한 자리로 이동시키면 옮겨지는 아이의 수를 최소로 하면서 줄을 세울 수 있습니다.
[41, 2, 3, 5] -> [1, 2, 3, 4, 5]

여기서 우리는 횟수만 구하면 되므로
전체 길이 - LIS(Longest Increasing Subsequence) 길이 = 아이의 최소 이동 횟수 = 원하는 답


저는 LIS Length를 구하는 과정에서 O(NlogN) 알고리즘을 사용하였습니다.
O(NlogN) 알고리즘은 아래 링크에서 참고해주세요


* 나의 코드

https://github.com/stack07142/BOJ/blob/ac068d64cd4734d854747b0c7887f9dfc57fdbeb/BOJ%232631/src/Main.java


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