🔺 문제
11053번: 가장 긴 증가하는 부분 수열
수열 A가 주어졌을 때, 가장 긴 증가하는 부분 수열을 구하는 프로그램을 작성하시오. 예를 들어, 수열 A = {10, 20, 10, 30, 20, 50} 인 경우에 가장 긴 증가하는 부분 수열은 A = {10, 20, 10, 30, 20, 50} 이
www.acmicpc.net
🔺 코드
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
|
import java.util.*;
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
int[] seq = new int[N + 1];
int[] dp = new int[N + 1]; // LIS 저장 배열
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
for(int i = 1 ; i <= N ; i++) {
seq[i] = Integer.parseInt(st.nextToken());
dp[i] = 1; // dp 값 1로 초기화
}
for(int i = 1 ; i <= N ; i++) {
for(int j = 1 ; j <= i ; j++) { // 1 ~ i 이전 원소들 탐색
if(seq[j] < seq[i] && dp[i] < dp[j] + 1) { // i가 j의 값보다 크고, 이전 dp 크기보다 작으면
dp[i] = dp[j] + 1;
}
}
}
int max = -1;
for(int i = 1 ; i <= N ; i++) {
max = Math.max(dp[i], max);
}
System.out.println(max);
}
}
|
cs |
✅ 해결 아이디어
✔ DP (Botom-Up)
디버깅해보면 대충 이렇게
🔺 다른 풀이들
- 과정 설명 굿..
[백준] 11053번 :가장 긴 증가하는 부분 수열 - JAVA [자바]
https://www.acmicpc.net/problem/11053 11053번: 가장 긴 증가하는 부분 수열 수열 A가 주어졌을 때, 가장 긴 증가하는 부분 수열을 구하는 프로그램을 작성하시오. 예를 들어, 수열 A = {10, 20, 10, 30, 20, 50} 인
wookong-lab.tistory.com
- 왜 dp[i] <= dp[j] 비교를 해야하나 싶었는데, 중복 방지를 위해서라는 걸 이 분 글 보고 깨달았당
[BOJ] 백준 11053번 : 가장 긴 증가하는 부분 수열 (JAVA)
문제의 링크 : https://www.acmicpc.net/problem/11053 11053번: 가장 긴 증가하는 부분 수열 수열 A가 주어졌을 때, 가장 긴 증가하는 부분 수열을 구하는 프로그램을 작성하시오. 예를 들어, 수열 A = {10, 20, 10
steady-coding.tistory.com
💬 느낀 점
후앙 어렵다,,,,
1회독 | 2회독 | 3회독 | 4회독 | 5회독 |
V | 7.19 | 8.2 | 24.1.18 |
(+7/19 2회독 : binary Search를 활용한 LIS 계산 풀이)
[Java]최장 증가 부분 수열(LIS, Longest Increasing Subsequence)
*최장 증가 부분 수열(LIS, Longest Increasing Subsequence) ->최장 증가 부분 수열이란, 주어진 수열에서 오름차순으로 정렬된 가장 긴 부분 수열을 찾는 문제이다. 여기서 부분 수열은 연속적이거나, 유
sskl660.tistory.com
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
import java.util.*;
import java.io.*;
public class Main {
static int N;
static int[] A, dp;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
N = Integer.parseInt(br.readLine());
A = new int[N];
dp = new int[N];
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
for(int i = 0 ; i < N ; i++) {
A[i] = Integer.parseInt(st.nextToken());
}
int LIS = 0; // 처음 저장된 원소는 없으므로 값은 0
for(int i = 0 ; i < N ; i++) {
int idx = binarySearch(A[i], 0, LIS, LIS + 1);
// 찾지 못한 경우, 가장 마지막 위치에 원소 삽입하고 LIS 길이 늘림
if(idx == -1) {
dp[LIS++] = A[i];
}
// 찾은 경우, 해당 위치에 현재 값 삽입해 갱신
else {
dp[idx] = A[i];
}
}
int ans = 0;
for(int i : dp) {
if(i != 0) {
ans++;
}
}
System.out.println(ans);
}
// 🔔 binary Search 활용한 LIS 🔔
private static int binarySearch(int num, int s, int e, int size) {
int pos = 0; // 원소 위치 기억용 변수
while(s <= e) {
int mid = (s + e) / 2;
if(num <= dp[mid]) {
pos = mid;
e = mid - 1;
}
else {
s = mid + 1;
}
}
// dp 테이블에 삽입될 위치를 못 찾은 경우
if(s == size) {
return -1;
}
// dp 테이블에 삽입될 위치를 찾은 경우
else {
return pos;
}
}
}
|
cs |
( + 8.2 3회독)
더 이해하기 좋은 풀이 발견!
알고리즘 풀이 - 백준 11053(가장 긴 증가하는 부분 수열, DP)
관련글 Dynamic Programming 관련 포스팅은 여기를 참조 LIS 관련 포스팅은 여기를 참조 1. 개요 문제 링크는 여기를 참조 문제의 내용을 보려면 아래 더보기 클릭 더보기 이 문제는 LIS의 길이를 구하는
hongjw1938.tistory.com
[DP] 백준 11053 가장 긴 증가하는 부분 수열 자바
ahnyezi.github.io
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
41
42
43
44
45
46
47
48
49
|
import java.util.*;
import java.io.*;
public class Main {
static int[] A, LIS;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
A = new int[N];
LIS = new int[N];
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
for(int i = 0 ; i < N ; i++) {
A[i] = Integer.parseInt(st.nextToken());
}
LIS[0] = A[0];
int end = 0;
for(int i = 1 ; i < N ; i++) {
if(LIS[end] < A[i]) {
LIS[++end] = A[i];
continue;
}
// LIS에 A[i]가 위치할 인덱스 찾아 해당 인덱스 값과 현재값 swap
int targetIdx = findIdx(end, i);
LIS[targetIdx] = A[i];
}
System.out.println(end + 1);
}
private static int findIdx(int end, int idx) {
int start = 0;
while(start <= end) {
int mid = (start + end) / 2;
if(LIS[mid] == A[idx]) return mid;
else if(LIS[mid] < A[idx]) start = mid + 1;
else if(LIS[mid] > A[idx]) end = mid - 1;
}
return start;
}
}
|
cs |
(+24.1.18 4회독)
단순한 방법을 찾았는데 왜 여지껏 어렵게 풀었는지,,,
이게 가장 간단한 풀이 방법 같다
코드 확인하기
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
|
import java.util.*;
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
int N = Integer.parseInt(br.readLine());
int[] A = new int[N];
st = new StringTokenizer(br.readLine(), " ");
for(int i = 0 ; i < N ; i++) {
A[i] = Integer.parseInt(st.nextToken());
}
int[] dp = new int[N];
Arrays.fill(dp, 1);
int max = 1;
for(int i = 0 ; i < N ; i++) {
for(int j = 0 ; j < i ; j++) {
if(A[i] > A[j]) {
dp[i] = Math.max(dp[i], dp[j] + 1);
max = Math.max(max, dp[i]);
}
}
}
System.out.println(max);
}
}
|
cs |
(참고)
[백준] 11053번 : 가장 긴 증가하는 부분 수열 - JAVA [자바]
www.acmicpc.net/problem/11053 11053번: 가장 긴 증가하는 부분 수열 수열 A가 주어졌을 때, 가장 긴 증가하는 부분 수열을 구하는 프로그램을 작성하시오. 예를 들어, 수열 A = {10, 20, 10, 30, 20, 50} 인 경우에
st-lab.tistory.com
'코테 > 백준' 카테고리의 다른 글
[백준/JAVA] 11054번: 가장 긴 바이토닉 부분 수열 (0) | 2023.06.04 |
---|---|
[백준/JAVA] 12865번: 평범한 배낭 (0) | 2023.06.03 |
[백준/JAVA] 2156번: 포도주 시식 (0) | 2023.06.02 |
[백준/JAVA] 2579번: 계단 오르기 (0) | 2023.06.01 |
[백준/JAVA] 1932번: 정수 삼각형 (0) | 2023.06.01 |