Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 문자열 압축
- 맛집
- 2638
- Servlet
- 스프링 MVC
- 투어
- 1로 만들기
- 고모네 콩탕
- BFS
- 서블릿
- 2839
- dp
- 설탕 배달
- 호유동
- 프로그래머스
- 맛집 투어
- 다이나믹 프로그래밍
- 양꼬치
- 스프링
- 쓰레드 풀
- 알고리즘
- 백준
- 포두부 보쌈
- 완도산회
- 2020 KAKAO BLIND
- 동적 프로그래밍
- 2589
- Spring
- HTTP API
- mvc
Archives
- Today
- Total
프로그래밍 공방
[백준] 11722번 : 가장 긴 감소하는 부분 수열 본문
문제 |
수열 A가 주어졌을 때, 가장 긴 감소하는 부분 수열을 구하는 프로그램을 작성하시오.
예를 들어, 수열 A = {10, 30, 10, 20, 20, 10} 인 경우에
가장 긴 감소하는 부분 수열은 A = {10, 30, 10, 20, 20, 10} 이고, 길이는 3이다.
입력 |
첫째 줄에 수열 A의 크기 N (1 ≤ N ≤ 1,000)이 주어진다.
둘째 줄에는 수열 A를 이루고 있는 Ai가 주어진다. (1 ≤ Ai ≤ 1,000)
출력 |
첫째 줄에 수열 A의 가장 긴 감소하는 부분 수열의 길이를 출력한다.
문제해결방법 |
먼저 이 문제를 해결하기 전에 LIS를 살펴보자.
LIS를 푸는 방법은 두 가지가 있다.
첫 번째 방법은 DP를 이용해서 푸는 방법이다.
현재 위치보다 앞에 있는 숫자들 중에 현재 숫자보다 값이 작은 수들의 DP값 중 최대 + 1
두 번째 방법은 증가하는 부분 수열을 만드는 수열들 중에 최적인 수열을 관리하는 배열 LIS을 만드는 것이다.
부분 수열의 마지막에 붙이려는 숫자가 LIS의 마지막 원소보다 크면, LIS의 배열의 마지막에 추가한다.
만약 작다면 LIS 배열 중에 붙이려는 숫자보다 큰 수들 중에 가장 앞에 있는 수(Lower Bound)와 교체해준다.
이번 문제는 위 방법 중 두 번째 방법을 약간 변형해서 풀었다.
코드 |
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 31 32 33 34 35 36 37 38 39 40 | package baekjoon; import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; import java.util.StringTokenizer; public class Main11722_가장긴감소하는부분수열 { public static int N; public static List<Integer> lds = new ArrayList<>(); public static int upperLimit(List<Integer> list, int num) { int si = 0, ei = list.size()-1; while(si<=ei) { int mi = (si+ei)/2; if(list.get(mi)<num) ei = mi-1; else if (list.get(mi)>num) si = mi+1; else return mi; } return si; } public static void main(String[] args) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); N = Integer.parseInt(br.readLine()); StringTokenizer st = new StringTokenizer(br.readLine()); lds.add(0); for(int i=0; i<N; i++) { int num = Integer.parseInt(st.nextToken()); if(lds.get(lds.size()-1)>num) lds.add(num); else { int index = upperLimit(lds, num); lds.set(index, num); } } System.out.println(lds.size()); } } | cs |
코드에 대한 피드백이나 더 좋은 아이디어는 언제나 환영입니다.
'개발 > 문제해결' 카테고리의 다른 글
[프로그래머스] 다리를 지나는 트럭 (0) | 2020.11.22 |
---|---|
[프로그래머스] 추석 트래픽 (0) | 2020.11.22 |
[백준] 9436번 : Round Robin (0) | 2020.11.21 |
[백준] 11057번 : 오르막 수 (0) | 2020.11.18 |
[백준] 14891번 : 톱니바퀴 (0) | 2020.11.17 |