1. ๋ฌธ์ ์ค๋ช
์์ด์ด ์ฃผ์ด์ก์ ๋, ๊ฐ์ฅ ๊ธด ์ฆ๊ฐํ๋ ๋ถ๋ถ ์์ด์ ๊ธธ์ด๋ฅผ ๊ตฌํ๊ณ , ํด๋น ์กฐ๊ฑด์ ๋ง์กฑํ๋ ๋ถ๋ถ ์์ด ์ค ํ๋๋ฅผ ์ถ๋ ฅํ๋ผ.
→ ์๋ ์ต์ฅ ์ฆ๊ฐ ๋ถ๋ถ ์์ด์ ๊ธธ์ด๋ง ๊ตฌํ๋ ๋ฌธ์ ์์ ์ด์ ๊ทธ ๊ตฌ์ฑ์์๋ฅผ ๊ตฌํ๋ ๋ฌธ์ ๋ก ๋ฐ๋์๋ค.
2. ํธ๋ ์๋ฆฌ
์ฒ์์ ๋ฌธ์ ํธ๋ ๋ฐ ์ ๋ง ํค๋งธ๋๋ฐ, ๊ทธ ์ด์ ๋ ํด๋น ๋ฌธ์ ๋ ๋ค๋ฅธ LIS์ฒ๋ผ ์ด๋ถํ์์ ์จ์ ํ๋ ค๊ณ ํ๊ธฐ ๋๋ฌธ์ด๋ค. ํ์ง๋ง ์ด๋ถํ์์ ๊ฒฝ์ฐ ํฐ ๋ฌธ์ ๊ฐ ์๋๋ฐ, ๋ฐ๋ก LIS์ ๊ตฌ์ฑ์์๋ฅผ ๊ตฌํ๊ธฐ ํ๋ค๋ค๋ ์ ์ด๋ค. ์ ๊ทธ๋ฐ์ง ํ๋ฒ ๋ณด์. ๋จผ์ ๊ฐ์ ๊ตฌํ๊ธฐ ์ํด ์กฐ์ํ๋ ๋ฐฐ์ด์ A, ์์ด ์ ์ฒด๋ฅผ ๋ด๋ ๋ฐฐ์ด์ T๋ผ๊ณ ํ์. Dp ํ์ด๋ฒ์์๋ A์ index i๋ T[i]๋ฅผ ๋ปํ๊ณ , A[i]๋ T[i]๋ฅผ ๋ ๊ฐ์ผ๋ก ๊ฐ์ง๋ LIS์ ํฌ๊ธฐ์ด๋ค. ์ด๋ถ ํ์ ํ์ด๋ฒ์์๋ A์ ์ธ๋ฑ์ค i๋ LIS์ ๊ธธ์ด๋ฅผ ๋ปํ๊ณ T[i]๋ LIS๊ฐ i๋ผ๋ ๊ธธ์ด์ผ ๋ ๋งจ ๋ ๊ฐ์ผ๋ก ๊ฐ์ง ์ ์๋ ์์์ ์ต์๊ฐ์ด๋ค. ๋ฐ๋ผ์ ์ ์์ธ DP ํ์ด๋ฒ์ ํ๋ฒ T[i]์ ๊ฐ์ ๊ตฌํ๋ฉด ํด๋น ๊ฐ์ด ๋ณ๋๋์ง ์๋๋ค. A[i]๊ฐ ๋งจ ๋ ๊ฐ์ธ LIS๋ ์์ด ์ ์ฒด๊ฐ ์ฃผ์ด์ง ์๊ฐ๋ถํฐ ์ด๋ฏธ ์ ํด์ ธ ์๊ธฐ ๋๋ฌธ์ด๋ค. ๋ฐ๋ฉด ์ด๋ถํ์์์์ T[i]๋ ๊ฐฑ์ ๋ ์ ์๋ค. ์๋ํ๋ฉด ๊ธธ์ด๊ฐ 3์ธ LIS๊ฐ์ด ๊ธฐ์กด์ 5์ธ ๊ฒฝ์ฐ, ์ ์ฒด ์์ด์ ์์๋ฅผ ํ๋ํ๋ ์ฝ์ด๊ฐ์๋ก ์ด๋ณด๋ค ๋ ์์ 3์ด ๋์ฌ ์๋ ์๊ธฐ ๋๋ฌธ์ด๋ค. ์ด๋ ๊ฒ ๊ฐ์ด ๊ณ์ ๋ฐ๋๋ค๋ฉด, ์ ์ฒด ๋ฐฐ์ด์ ๊ตฌํ๊ณ LIS๋ฅผ ๊ตฌํ ๋ค์ ๋ค์ ๋ณต๊ธฐ ํด๊ฐ๋ฉฐ, ์ต์ฅ ๊ธธ์ด ๋ถ๋ถ ์์ด์ ๋ฉค๋ฒ๋ฅผ ๊ตฌํ๋ค๋ ๊ฒ์ ์ฝ์ง ์๋ค. ์ฐจ๋ผ๋ฆฌ ๊ณ ์ ๋ถ๋ณ์ A[i]๋ฅผ ๊ฐ์ง DP ํ์ด๋ฒ์ ์ฐ๋ ๊ฒ์ด LIS์ ๋ฉค๋ฒ๋ฅผ ๊ตฌํ๊ธฐ์ ๋์ฑ ์ฉ์ดํ๋ค.
๋ฐ๋ผ์ ์์ ์ด์ ๋๋ฌธ์ DP ํ์ด๋ฒ์ ์ด์ฉํ๋ค. DP๋ ์ฃผ์ด์ง ์ ์ฒด ์์ด์ ์์๋ฅผ ์ฒซ ๊ฐ๋ถํฐ ํ๋ํ๋ ๊ตฌํด๋๊ฐ๋ฉฐ, ๊ทธ ์ํฉ์์์ ๋ถ๋ถ ์ฆ๊ฐ ์์ด์ ๊ธธ์ด๋ฅผ ๊ตฌํ๋ค. → stack up์ด ์ด๋ฃจ์ด์ง๋ค๋ ๊ฒ์ด๋ค. (ํ๋ ํ๋์ฉ ๊ฐฑ์ ๋์ด๊ฐ๋ฉฐ ์์๋๊ฐ๋ค.) ์์ ๋ฌธ์ ๋ LIS์ ๊ตฌ์ฑ์์๋ ๊ฐ์ด ๊ตฌํ๋ผ๊ณ ํ์ผ๋ฏ๋ก, DP๋ก ์์ ํ๋ํ๋์ฉ ๊ตฌํด๊ฐ๋ฉด์, ๋ถ๋ถ ์ฆ๊ฐ ์์ด์ ๊ธธ์ด๊ฐ ์ปค์ง ๋๋ง๋ค, ์ถ๊ฐ๋๋ ์์๋ฅผ ๋ค๋ฅธ ๊ณณ์๋ค๊ฐ ์ ์ฅํด๋๋ค. ๋๋ LIS DP ํ์ด๋ฒ๊ณผ ๋ณ๊ฐ๋ก StringBuilder ArrayList๋ฅผ ๊ฐ์ง๊ณ ์์๋ค. ๊ทธ๋ฆฌ๊ณ ๋ง์ฝ ๋ถ๋ถ์ฆ๊ฐ์์ด์ ๊ธธ์ด๊ฐ ๊ธธ์ด์ง ๋, ํ์ฌ ์กฐํ ์ค์ธ ์ธ๋ฑ์ค๊ฐ i์ด๋ฉด T[i]๋ฅผ ๋ ๊ฐ์ผ๋ก ๊ฐ์ง๋ LIS๋ฅผ ArrayList.get(i)๋ฒ์ ์ ์ฅํ๋ค.
3. ์ฝ๋ ๋ถ์
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 [] arr = new int [N+1];
// ๊ฐ ์ธ๋ฑ์ค๊ฐ ํด๋น arr[i]๋ฅผ ๋ง์ง๋ง์ผ๋ก ํ๋ ์ต์ฅ ์ฐ์ ์์ด์ ๊ฐ๋ค์ด ์ ์ฅ๋์ด ์์.
ArrayList<StringBuilder> LIS = new ArrayList<>();
// index -> arr์ index๋ฅผ ๊ฐ๋ฆฌํด
// ๊ฐ -> ๋ฐฐ์ด ์ ํด๋น ์ธ๋ฑ์ค์ ๊ฐ์ ๋์ผ๋ก ํ๋ ์ต์ฅ ์ฐ์ ์์ด์ ๊ธธ์ด
int [] dp = new int [N+1];
StringTokenizer st = new StringTokenizer(br.readLine());
for (int i = 1; i <= N; i++) {
arr[i] = Integer.parseInt(st.nextToken());
}
Arrays.fill(dp, 1);
dp[0] = 0;
LIS.add(new StringBuilder());
LIS.add(new StringBuilder().append(arr[1]).append(" "));
for (int i = 2; i <= N; i++) {
int max = 1;
int maxIndex = 0;
for (int j = 1; j <= i; j++) {
if(arr[j] < arr[i]){
// ์ง๊ธ๊น์ง ์์๋ณธ ์ต์ฅ ๊ธธ์ด๋ณด๋ค ๋ ๊ธด ์์ด์ด ๊ฐ๋ฅํ๋ค.
if(max < dp[j] + 1){
// ๊ธธ์ด ๊ฐฑ์ , ๋งจ ๋๊ฐ์ index ๊ธฐ๋ก
max = dp[j] + 1;
maxIndex = j;
}
}
}
dp[i] = max;
// arr[i]๋ฅผ ๋งจ ๋์ ๋ฃ์ ์ ์๋ ์ต์ฅ ์ฐ์ ์์ด + arr[i]์ ๊ฐ
LIS.add(new StringBuilder().append(LIS.get(maxIndex)).append(arr[i]).append(" "));
}
int maxDP = 0;
int maxDPIndex = 0;
for (int i = 0; i < dp.length; i++) {
if(dp[i] > maxDP){
maxDPIndex = i;
maxDP = dp[i];
}
}
System.out.printf("%d \n%s", maxDP, LIS.get(maxDPIndex));
}
}