메모리: 14784 KB, 시간: 144 ms
다이나믹 프로그래밍, 가장 긴 증가하는 부분 수열: O(n log n)
2024년 8월 26일 22:32:43
N명의 병사가 무작위로 나열되어 있다. 각 병사는 특정한 값의 전투력을 보유하고 있으며, 병사를 배치할 때는 전투력이 높은 병사가 앞쪽에 오도록 내림차순으로 배치를 하고자 한다. 다시 말해 앞쪽에 있는 병사의 전투력이 항상 뒤쪽에 있는 병사보다 높아야 한다.
또한 배치 과정에서는 특정한 위치에 있는 병사를 열외시키는 방법을 이용한다. 그러면서도 남아있는 병사의 수가 최대가 되도록 하고 싶다.
예를 들어, N=7일 때 나열된 병사들의 전투력이 다음과 같다고 가정하자.
이 때 3번 병사와 6번 병사를 열외시키면, 다음과 같이 남아있는 병사의 수가 내림차순의 형태가 되며 5명이 된다. 이는 남아있는 병사의 수가 최대가 되도록 하는 방법이다.
병사에 대한 정보가 주어졌을 때, 남아있는 병사의 수가 최대가 되도록 하기 위해서 열외해야 하는 병사의 수를 출력하는 프로그램을 작성하시오.
첫째 줄에 N이 주어진다. (1 ≤ N ≤ 2,000) 둘째 줄에 각 병사의 전투력이 공백을 기준으로 구분되어 차례대로 주어진다. 각 병사의 전투력은 10,000,000보다 작거나 같은 자연수이다.
첫째 줄에 남아있는 병사의 수가 최대가 되도록 하기 위해서 열외해야 하는 병사의 수를 출력한다.
풀이
LIS 알고리즘이란 Longest Increasing Subsequnce로 증가하는 가장 긴 부분수열을 찾는 알고리즘이다.
10 20 10 30 20 50 이란 배열이 있을 때
위의 배열에서 숫자 몇 개를 빼서 가장 긴 오름차순 배열을 만들어야 한다.
위의 예시를 보면 10과 20을 뺏을 때
10 20 30 50 으로 가장 긴 오름차순 배열을 만들 수 있다.
위와 같은 오름차순 배열을 만들기 위해 나는 다음과 같은 방식을 사용했다.
dp 배열을 모두 1로 초기화 시킨후
만약 현재 방문한 노드 보다 값이 큰 노드가 있다면 Math.max(dp[now]+1, dp[bigger])
로 dp[bigger]에 값을 넣어 dp[bigger]의 값을 초기화 시켜준다.
첫 번째 행부터 이중 포문으로 전체 배열을 돌면서 자기보다 큰 놈에게 위의 식을 적용시킨다면,
오름차순의 가장 긴 배열의 값을 찾을 수 있을 것이다.
전체 코드
public class Main {
static int s;
public static void main(String args[])throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
s = Integer.parseInt(br.readLine());
int dp[] = new int[s];
int x[] = new int[s];
StringTokenizer st = new StringTokenizer(br.readLine());
int max = 0;
for(int i = 0 ;i<s;i++){
x[i] = Integer.parseInt(st.nextToken());
dp[i] = 1;
max = Math.max(max,x[i]);
}
max = 1;
for(int i = 0 ;i<s;i++){
for(int j = i+1 ;j<s;j++){
if(x[i] > x[j]){
dp[j] = Math.max(dp[i]+1, dp[j]);
}
max = Math.max(dp[j],max);
}
}
bw.write("" + (s-max));
bw.flush();
}
}
'코딩 테스트 연습 > 백준' 카테고리의 다른 글
백준 1010번 다리 놓기 (java) (3) | 2024.08.28 |
---|---|
백준 11053번 가장 긴 증가하는 부분수열 (java) (0) | 2024.08.27 |
백준 1463번 1로 만들기 (java) (0) | 2024.08.25 |
백준 19621번 회의실 배정 (java) (0) | 2024.08.18 |
백준 5567번 결혼식 (java) (0) | 2024.08.18 |