https://www.acmicpc.net/problem/11053
11053번: 가장 긴 증가하는 부분 수열
수열 A가 주어졌을 때, 가장 긴 증가하는 부분 수열을 구하는 프로그램을 작성하시오. 예를 들어, 수열 A = {10, 20, 10, 30, 20, 50} 인 경우에 가장 긴 증가하는 부분 수열은 A = {10, 20, 10, 30, 20, 50} 이
www.acmicpc.net
스터디 문제로 바이토닉 수열 문제가 있었는데,
그 문제를 풀기 전에 이 문제부터 풀어보면 좋을듯 하여 먼저 풀어보았다.
다행이도 어제 공부한걸 까먹진 않았는지 질 풀렸다.
수열과 같은 길이의 배열 dp[]를 선언하고 dp의 각 위치에 해당 위치까지 올수있는 가능한 수열의 길이값을 할당한다.
이중 가장 큰 길이값이 나오는걸 max변수에 저장하고 출력했다.
이중 for문과
if (nums[j] < nums[i] && dp[j] + 1 > dp[i]) {
dp[i] = dp[j] + 1;
}
이 부분이 핵심!
전체 풀이코드:
package week1;
import java.io.*;
import java.util.StringTokenizer;
public class PartialSequence { //백준 11053번 가장 긴 증가 부분수열 문제
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
int N = Integer.parseInt(br.readLine()); //수열의 크기 입력받음
StringTokenizer st = new StringTokenizer(br.readLine()); //수열 입력받음
int[] nums = new int[N];
int[] dp = new int[N]; //N크기만큼의 Dp배열 생성, 여기에 각 수열값들 위치까지의 최대 부분수열 길이가 들어갈것임
int max = 0; //가장 긴 부분수열 길이
for (int i = 0; i < N; i++) {
nums[i] = Integer.parseInt(st.nextToken());
dp[i] = 1; //기본적으로 1이 들어간다(자기 자신 하나가 일단 원소니까 최소 길이는 모두 1씩)
for (int j = 0; j < i; j++) {
if (nums[j] < nums[i] && dp[j] + 1 > dp[i]) {
/*증가하는 수열이 되어야 하니까 일단 j 원소의 크기가 i보다 작은지부터 확인,
dp[j]의 값, 즉 j번째 원소 다음에 i번째 원소가 오도록 수열을 만드는게 이득이면 dp[i] 갱신 */
dp[i] = dp[j] + 1;
}
}
if(max < dp[i]) max = dp[i]; //안쪽For문에 뒀다가 바깥으로 뺐다(원소가 하나뿐이라면 안쪽For문 못도니까 이경우도 고려)
}
bw.write(Integer.toString(max));
bw.flush();
bw.close();
}
}
'알고리즘 > dp' 카테고리의 다른 글
[SWEA] Test샘플문제 - 1952번 수영장 문제 (dp풀이) (0) | 2023.05.05 |
---|---|
[백준알고리즘] dp - 2225번 합분해 문제 (0) | 2023.04.03 |
[백준알고리즘] dp - 9466번 스티커 문제 (0) | 2023.04.02 |
[백준알고리즘] dp - 11054번 바이토닉 부분 수열 문제 (0) | 2023.04.01 |
[백준알고리즘] dp - 11055번 가장 큰 증가하는 부분 수열 문제 (0) | 2023.03.31 |