250x250
Notice
Recent Posts
Recent Comments
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 29 | 30 |
Tags
- 막내의막무가내 플러터
- 막내의 막무가내 알고리즘
- 막내의막무가내 알고리즘
- 막내의 막무가내
- 막내의막무가내 프로그래밍
- Fragment
- 주엽역 생활맥주
- 부스트코스
- 막내의막무가내 목표 및 회고
- 안드로이드 Sunflower 스터디
- 주택가 잠실새내
- 프래그먼트
- 부스트코스에이스
- 막내의막무가내 안드로이드 코틀린
- 막내의막무가내 코볼 COBOL
- flutter network call
- 막내의막무가내
- 막내의막무가내 일상
- 막무가내
- 막내의막무가내 SQL
- 안드로이드
- 막내의막무가내 코틀린
- 막내의막무가내 rxjava
- 프로그래머스 알고리즘
- 막내의막무가내 안드로이드
- 2022년 6월 일상
- 안드로이드 sunflower
- 막내의막무가내 플러터 flutter
- 막내의막무가내 코틀린 안드로이드
- 막내의막무가내 안드로이드 에러 해결
Archives
- Today
- Total
막내의 막무가내 프로그래밍 & 일상
[알고리즘] 백준 2565 전깃줄 -dp- 본문
728x90
https://www.acmicpc.net/problem/2565
이어 단계별 dp 문제를 풀어봤습니다. LIS 라는 것을 안보고 그냥 풀었었는데 LIS 개념은 다음 사이트나 구글링을 통해 볼 수 있습니다. Longest Increasing Subsequence, 최장증가부분수열 입니다.
전깃줄 합선이 안되게 최소로 제거해야할 전깃줄을 구하는 문제였습니다. 역발상으로 전깃줄 제거가 아닌 최대 설치개수를 dp, LIS 로 구하고 최대 개수에서 뺴면 간단해지는 문제였습니다.
A전깃줄로 먼저 오름차순 정렬을 하여(그럼 반복문 돌며 B만 값 비교하여 신경쓰면 됨) 최대로 합선안되게 설치할 수 있는 전깃줄의 개수를 구하고 전체 개수에서 뺌으로써 최소제거 개수 결과를 도출할 수 있었습니다.
설명은 주석에 적어놨습니다.
풀이는 다음과 같습니다.
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[][] num = new int[n + 1][2]; //[][1] : A 전깃줄 번호, [][2] : B 전깃줄 번호
int[] dp = new int[n + 1]; // 해당 위치까지의 가장 많이 설치할 수 있는 전깃줄 개수
int maxInstall = 1; //가장 많이 설치할 수 있는 개수
for (int i = 1; i <= n; i++) {
num[i][0] = sc.nextInt();
num[i][1] = sc.nextInt();
}
//[][0] 정렬 (A 전봇대 기준으로)
Arrays.sort(num, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return o1[0] - o2[0];
}
});
for (int i = 1; i <= n; i++) {
dp[i] = 1;
for (int j = 1; j < i; j++) {
if (num[j][1] < num[i][1]) { // 과거 A의 전깃줄과 이어진 B 번호보다 현재 B 번호가 더 커야 이을 수 있다.(A보다큰)
dp[i] = Math.max(dp[i], dp[j] + 1); // 과거 최대 전깃줄 개수 + 1 세팅
}
}
maxInstall = Math.max(maxInstall, dp[i]); // 최대 전깃줄 개수 세팅
}
System.out.println(n - maxInstall); //없애야 하는 전깃줄의 최소 개수 = 전체개수 - 가장많이설치할 수 있는 개수
}
}
추가로 저는 원래 for 반복문에서 이전에 풀었던 비슷한 dp 문제들 처럼
for (int i = 1; i <= n; i++) {
int max = 0;
for (int j = 1; j < i; j++) {
if (max < dp[j] && num[j][1] < num[i][1]) { // 과거 A의 전깃줄과 이어진 B 번호보다 현재 B 번호가 더 커야 이을 수 있다.(A보다큰)
max = dp[j];
}
}
dp[i] = max + 1;
maxInstall = Math.max(maxInstall, dp[i]); // 최대 전깃줄 개수 세팅
}
이런식으로 풀었었습니다. 그러나 밑 블로그 분의 풀이를 참고하고 이분의 코드가 더 깔끔하고 정석인 것 같아 코드를 바꾸고 앞으로도 비슷한 문제가 나오면 이렇게 풀려고 합니다.
https://hooongs.tistory.com/archive/20200111
댓글과 공감은 큰 힘이 됩니다.
728x90
Comments