https://www.acmicpc.net/problem/2565
2565번: 전깃줄
첫째 줄에는 두 전봇대 사이의 전깃줄의 개수가 주어진다. 전깃줄의 개수는 100 이하의 자연수이다. 둘째 줄부터 한 줄에 하나씩 전깃줄이 A전봇대와 연결되는 위치의 번호와 B전봇대와 연결되는
www.acmicpc.net
난이도 : G5
유형 : LIS, DP
비슷한 문제
https://www.acmicpc.net/problem/7578
7578번: 공장
어떤 공장에는 2N개의 기계가 2열에 걸쳐 N개씩 배치되어 있다. 이 2개의 열을 각각 A열과 B 열이라고 부른다. A열에 있는 N개의 기계는 각각이 B열에 있는 N개의 기계와 하나씩 짝을 이루어 케이블
www.acmicpc.net
문제 풀이
세그먼트 트리로도 풀리지만 LIS 풀이가 더 쉬워서 LIS로 풀었다.
필자는 최장증가부분수열(LIS) 개념을 알고 있어서 쉽게 접근할 수 있었다.
문제에선 최소의 갯수를 물어보지만 역발상으로 최대의 개수에 초점에 맞추면 풀이가 더 쉬워진다.
설치된 전선을 왼쪽 번호 기준으로 정렬한 후
앞에서부터 순차적으로 탐색하면서 자신보다 오른쪽 번호가 작은 전선을 카운팅 하며 dp테이블을 갱신하면 된다.
예시)
예시 케이스입력을 정렬한 상태
1 - 8 -> dp[1] = 1, 1개(본인)만 설치가능
2 - 2 -> dp[2] = 1, 이전의 전선의 오른쪽(8)이 자신보다 크기 때문에 본인만 설치가능, 1개
3 - 9 -> dp[3] = 2, 본인과 첫 번째 줄 가능(dp[1] + 1) 혹은 본인과 두 번째 줄 가능(dp[2] + 1)
4 - 1 -> dp[4] = 1, 1개(본인)만 설치가능
6 - 4 -> dp[5] = 2, 본인과 두 번째 줄 가능(dp[2] + 1) 혹은 본인과 네 번째 줄 가능(dp[4 + 1)
7 - 6. -> dp[6] = 3, dp[5] + 1
9 - 7. ->. dp[7] = 4, dp[6] + 1
10 - 10. -> dp[8] = 5, dp[7] + 1
이렇게 현재 전선의 오른쪽 값보다 작은 이전의 전선들의 dp에 +1 하여 최댓값을 갱신해 나가면 된다.
코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;
public class Main {
class Line implements Comparable<Line> {
int left;
int right;
public Line(int left, int right) {
this.left = left;
this.right = right;
}
@Override
public int compareTo(Line o) {
return this.left - o.left;
}
}
private int N;
private Line[] lines;
private int[] dp;
public void solution() throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
N = Integer.parseInt(br.readLine());
lines = new Line[N];
dp = new int[N];
for (int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
lines[i] = new Line(Integer.parseInt(st.nextToken()), Integer.parseInt(st.nextToken()));
}
Arrays.sort(lines);
int max = 1;
for (int i = 0; i < N; i++) {
dp[i] = 1;
for (int j = 0; j < i; j++) {
if (lines[i].right > lines[j].right) {
dp[i] = Math.max(dp[i], dp[j] + 1);
}
}
max = Math.max(max, dp[i]);
}
System.out.println(N - max);
}
public static void main(String[] args) throws IOException {
new Main().solution();
}
}
'Algorithm, Problem Solving > 백준(boj)' 카테고리의 다른 글
[백준][Java] 11292 - 키 큰 사람 (0) | 2023.03.24 |
---|---|
[백준][Java] 17070 - 파이프 옮기기 1 (0) | 2023.03.24 |
[백준][Java] 24228 - 젓가락 (0) | 2023.03.23 |
[백준][java] 25644 - 최대 상승 (0) | 2023.03.22 |
[백준][java] 10431 - 줄세우기 (0) | 2023.03.22 |
댓글