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
์๊ณ ๋ฆฌ์ฆ [์ ๊ทผ ๋ฐฉ๋ฒ]
๋ณดํต ์ด๋ฐ ๋ฌธ์ ๋ฅผ ์ต์ฅ ์ฆ๊ฐ ๋ถ๋ถ ์์ด(LIS)๋ผ๊ณ ํ๋ค. ๋ง ๊ทธ๋๋ ์ฃผ์ด์ง ์์ด์์ ์ค๋ฆ์ฐจ ์์ผ๋ก ๊ตฌ์ฑ ๊ฐ๋ฅํ ์์๋ค์ ์ ํํ์ฌ ์ต๋ ๊ธธ์ด๋ฅผ ์ฐพ์๋ด๋ ๊ฒ์ด๋ค. ์ ํ์ฉํ๋ฉด O(N log N)์ ์๊ฐ ๋ณต์ก๋๋ฅผ ๊ฐ๋๋ค.
์์ ๋ฅผ ๋ณด์๋ฉด ์ ์์ด์ {10, 20, 10, 30, 20, 50} ์ด๋ค. ์ด๋ฅผ seq๋ผ๊ณ ํ๊ณ , DP[]๋ฐฐ์ด์ ๋ฉ๋ชจ์ด์ ์ด์ ์ ํ๋ค.
๋จผ์ seq[0] = 10์ ๋ํ ์์ด์ ์ฐพ์๋ณด์๋ฉด seq[0]๋ณด๋ค ์ด์ ๊ฐ์ ์์ผ๋ฏ๋ก 10 ์์ฒด ํ๋๋ฐ์ ์กด์ฌํ์ง ์์ผ๋ฏ๋ก DP[0] = 1์ด๋๋ค. ๊ทธ ๋ค์ seq[1] = 20์ ๋ํ ์์ด์ ์ฐพ์๋ณด๋ฉด seq[0] = 10์ผ๋ก 20๋ณด๋ค ์๊ธฐ ๋๋ฌธ์ {10,20}์ด๋ผ๋ ๋ถ๋ถ ์์ด์ด ๋๊ณ , ๊ธธ์ด๋ 2๋ก DP[1] = 2๊ฐ ๋๋ ๊ฒ์ด๋ค. seq[2] = 10์ ๊ฒฝ์ฐ ์ด์ ๊ฐ๋ค ์ค ์์๊ฒ ์์ผ๋ฏ๋ก {10} ํ๋๋ง ๋๋ฏ๋ก DP[2] = 1์ด๋๊ณ ์ด๋ฐ์์ผ๋ก ์งํํ๋ ๊ฒ์ด๋ค.
์ฆ ๊ฐ dp[] ์ ๊ธธ์ด๋ค์ ๋ค์ ๋ถ๋ถ ์์ด์ ์๋ฏธํ๋ ๊ฒ์ด๋ค.
dp[0] = {10} : ๊ธธ์ด 1
dp[1] = {10, 20} : ๊ธธ์ด 2
dp[2] = {10} : ๊ธธ์ด 1
dp[3] = {10, 20, 30} : ๊ธธ์ด 3
dp[4] = {10, 20} : ๊ธธ์ด 2
dp[5] = {10, 20, 30, 50} : ๊ธธ์ด 4
๊ตฌํํ๋ ๋ฐฉ๋ฒ์ ํ์ํ๋ ค๋ ์ธ๋ฑ์ค(์์น)์ ๋ํด์ ์ด์ ์์น๋ค์ ์ฐพ์๋๊ฐ๋ฉด์ ํด๋น๊ฐ๋ณด๋ค ์์ ๊ฒฝ์ฐ ์ฌ๊ทํธ์ถ์ ํตํด ํ์ํด๋๊ฐ๋ฉด ๋๋ค.
static int LIS(int N) {
// ๋ง์ฝ ํ์ํ์ง ์๋ ์์น์ ๊ฒฝ์ฐ
if(dp[N] == null) {
dp[N] = 1; // 1๋ก ์ด๊ธฐํ
// N ์ด์ ์ ๋
ธ๋๋ค์ ํ์
for(int i = N - 1; i >= 0; i--) {
// ์ด์ ์ ๋
ธ๋ ์ค seq[N]์ ๊ฐ๋ณด๋ค ์์ ๊ฑธ ๋ฐ๊ฒฌํ์ ๊ฒฝ์ฐ
if(seq[i] < seq[N]) {
dp[N] = Math.max(dp[N], LIS(i) + 1);
}
}
}
return dp[N];
}
์ ์ฝ๋๋ฅผ ๋ณด๋ฉฐ ์ดํดํด๋ณด์๋ฉด,
๋จผ์ n๋ฒ์งธ ๊ฐ์ ๋ํด ์ด์ ์ ํ์ํ ๊ฒฐ๊ณผ๋ฌผ์ด ์๋์ง๋ฅผ ๊ฒ์ฌํ๋ค.
๋ง์ฝ ์๋ค๋ฉด ํ์ํ์ง ์์๋ค๋ ์๋ฏธ์ด๋ฏ๋ก DP[N]์ 1๋ก ์ด๊ธฐํํ๋ ๊ฒ์ด๋ค. ์ด์ ๋ ๋ชจ๋ ๋ถ๋ถ์์ด์ ๊ธธ์ด๋ '์ต์ํ 1์ด์'์ด๊ธฐ ๋๋ฌธ์ด๋ค.
๊ทธ๋ฆฌ๊ณ ๋ ๋ค, N-1 ๋ถํฐ 0๊น์ง N๋ณด๋ค ์์ ๋ ธ๋๋ค์ ํ์ํ๋ฉด์ ํด๋น ๋ ธ๋์ ๊ฐ์ด N๋ฒ์งธ ๊ฐ๋ณด๋ค ์์ ๊ฒฝ์ฐ๋ฅผ ์ฐพ๋ ๊ฒ์ด๋ค. ์ ์์๋๋ก๋ผ๋ฉด N=4์ ํ์ํ๊ณ ์ ํ ๋, 3~0๊น์ง ํ์ํ๋ฉด์ ์์ ๊ฐ๋ค์ด ์กด์ฌํ๋ ๊ฒฝ์ฐ๋ seq[2] = 10 ๊ณผ seq[0] = 10 ๋ฐ์ ์๋ค. ์ฆ, ๋ฐ๋ณต๋ฌธ i๋ 2์์ ํ๋ฒ ์ฌ๊ทํ์์ ์์ํ๊ณ , 0์์ ์ฌ๊ทํ์์ ์์ํ๋ ๊ฒ์ด๋ค.
i=2์์ ํ์ฌ ํ์ํ๊ณ ์ ํ๋ ๊ฐ DP[4]์ LIS(2) + 1 ์ฌ๊ทํธ์ถํ ๊ฐ ์ค ํฐ ๊ฐ์ DP[4]์ ๊ฐฑ์ ์ํค๋ ๊ฒ์ด๋ค. ์ฌ๊ธฐ์ ๋น์ฐํ +1์ ํ๋ ์ด์ ๋ DP[N]์ด ์ด์ ๋ถ๋ถ์ N๋ฒ์งธ ์์๊ฐ ์ถ๊ฐ๋์๋ค๋ ์๋ฏธ์ด๊ธฐ ๋๋ฌธ์ด๋ค.
LIS(2) ์ฌ๊ทํธ์ถ์ ํ๋ฉด DP[2]์ ์์ง ํ์ํ์ง ์์์ ๊ฒฝ์ฐ DP[2] = 1๋ก ์ด๊ธฐํ๋๊ณ , ๋ํ 0~1๊น์ง ์ค ์์ ๊ฐ๋ค์ ์ฐพ์๋ธ๋ค. ์ด ๋ ์ด ๋ถ๋ถ์์ seq[2] = 10๋ณด๋ค ์์ ๊ฐ์ ์์ผ๋ฏ๋ก DP[N] = 1์ด ๋ฐํ๋๋ค.
๋ค์ ๋์์ DP[4]์ LIS(2) + 1์ค, ํฐ ๊ฐ์ LIS(2) + 1 (= ๋ถ๋ถ์์ด {10, 20}), ์ฆ 2์ด๊ธฐ ๋๋ฌธ์ DP[4]๋ 2๋ก ๊ฐฑ์ ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋ฐ๋ณต๋ฌธ์ ๋ง์ ํ์ํ๋ฉด i=0์ผ ๋ seq[0] < seq[4]๋ฅผ ๋ง์กฑํ๋ฏ๋ก ์ฌ๊ทํ์์ ํ๊ฒ ๋๋๋ฐ ๋ง์ฐฌ๊ฐ์ง๋ก LIS(0) ๋ํ 1์ด๋ฏ๋ก ์ต๋ ๊ธธ์ด๊ฐ 2๊ฐ ๋๋ค.
for(int i = 0; i < N; i++) {
dp[i] = 1;
// 0 ~ i ์ด์ ์์๋ค ํ์
for(int j = 0; j < i; j++) {
// j๋ฒ์งธ ์์๊ฐ i๋ฒ์งธ ์์๋ณด๋ค ์์ผ๋ฉด์ i๋ฒ์งธ dp๊ฐ j๋ฒ์งธ dp+1 ๊ฐ๋ณด๋ค ์์๊ฒฝ์ฐ
if(seq[j] < seq[i] && dp[i] < dp[j] + 1) {
dp[i] = dp[j] + 1; // j๋ฒ์งธ ์์์ +1 ๊ฐ์ด i๋ฒ์งธ dp๊ฐ ๋๋ค.
}
}
}
๋ฐ๋ณต๋ฌธ์ผ๋ก ๊ตฌํํ ์ ์๋ค. ๋ฐฉ์์ ์ด์ค๋ฐ๋ณต๋ฌธ์ผ๋ก 0 ~ N-1 ๊น์ง ๊ฐ ์์๋ณด๋ค ํฐ ๊ฐ๋ค์ ์นด์ดํ ํด์ฃผ๋ ๊ฒ์ด๋ค.
ํ์ด ๋ฐ ์ฝ๋
- ๋ฐฉ๋ฒ 1 : [Scanner + Top-Down]
import java.util.Scanner;
public class Main {
static int[] seq;
static Integer[] dp;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int N = in.nextInt();
seq = new int[N];
dp = new Integer[N];
for(int i = 0; i < N; i++) {
seq[i] = in.nextInt();
}
// 0 ~ N-1 ๊น์ง ๋ชจ๋ ๋ถ๋ถ์์ด ํ์
for(int i = 0; i < N; i++) {
LIS(i);
}
int max = dp[0];
// ์ต๋๊ฐ ์ฐพ๊ธฐ
for(int i = 1; i < N; i++) {
max = Math.max(max, dp[i]);
}
System.out.println(max);
}
static int LIS(int N) {
// ๋ง์ฝ ํ์ํ์ง ์๋ ์์น์ ๊ฒฝ์ฐ
if(dp[N] == null) {
dp[N] = 1; // 1๋ก ์ด๊ธฐํ
// N-1 ๋ถํฐ 0๊น์ง์ค N๋ณด๋ค ์์ ๊ฐ๋ค์ ์ฐพ์ผ๋ฉด์ ์ฌ๊ทํธ์ถ.
for(int i = N - 1; i >= 0; i--) {
if(seq[i] < seq[N]) {
dp[N] = Math.max(dp[N], LIS(i) + 1);
}
}
}
return dp[N];
}
}
main ์์ LIS() ์ 0~ N-1 ๊น์ง ๋ชจ๋ ๊ฐ์ ๋ํ์ฌ ๋ฐ๋์ ํ์ํด์ผ ํ๋ค. ๊ทธ๋์ผ ๊ฐ๊ฐ์ ์์์ ๋ํ ๋ถ๋ถ ์ฆ๊ฐ ์์ด์ ๋ชจ๋ ๊ตฌํ ์๊ฐ ์๋ค.
- ๋ฐฉ๋ฒ 2 : [Scanner + Bottom-Up]
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int N = in.nextInt();
int[] seq = new int[N];
int[] dp = new int[N];
for(int i = 0; i < N; i++) {
seq[i] = in.nextInt();
}
// dp
for(int i = 0; i < N; i++) {
dp[i] = 1;
// 0 ~ i ์ด์ ์์๋ค ํ์
for(int j = 0; j < i; j++) {
// j๋ฒ์งธ ์์๊ฐ i๋ฒ์งธ ์์๋ณด๋ค ์์ผ๋ฉด์ i๋ฒ์งธ dp๊ฐ j๋ฒ์งธ dp+1 ๊ฐ๋ณด๋ค ์์๊ฒฝ์ฐ
if(seq[j] < seq[i] && dp[i] < dp[j] + 1) {
dp[i] = dp[j] + 1; // j๋ฒ์งธ ์์์ +1 ๊ฐ์ด i๋ฒ์งธ dp๊ฐ ๋๋ค.
}
}
}
// ์ต๋๊ฐ(์ต๋ ๊ธธ์ด) ํ์
int max = -1;
for(int i = 0; i < N; i++) {
max = dp[i] > max ? dp[i] : max;
}
System.out.println(max);
}
}