자료구조, 알고리즘/문제풀이

[알고리즘] 가장 긴 증가하는 부분 수열 - 백준 11053

wnstjd 2024. 6. 2. 23:19

문제

 

 

풀이

표를 그려서 생각하는 것이 좋을 것 같다.

index 0 1 2 3 4 5 6
arr 0 10 20 10 30 20 50
dp 0            

 

내가 생각한 방법은 간단하다. 

arr[0] ~ arr[i - 1]까지 탐색을 하며 arr[i]가 속할 수 있는 수열 중 가장 긴 수열의 길이를 dp[i]에 저장하는 것이다. 

 

1. arr[0] ~ arr[i-1]까지 탐색

2. 탐색 중 arr[i]보다 작은 값을 발견하였고 그 값의 dp값이 지금까지의 dp값보다 작다면 발견한 수의 dp값을 따로 저장

3. 탐색 종료 후 dp[i] = 발견한 가장 큰 dp값 + 1로 수열 길이 구하기

 

위의 로직으로 dp값을 구하면 아래처럼 구해진다.

index  0 1 2 3 4 5 6
arr 0 10 20 10 30 20 50
dp 0 1
(dp[0] + 1)
2
(dp[1] + 1)
1
(dp[0] + 1)
3
(dp[2] + 1)
2
(dp[1] + 1)
4
(dp[4] + 1)

 

이 문제는 길게 설명할 필요 없이 코드를 보는 것이 좋을 것 같다.

 

 

코드

#include<iostream>
using namespace std;

int arr[1001], dp[1001], n;

int solution()
{
	int maxNum = 0;

	for (int i = 1; i <= n; i++)
	{
		maxNum = 0;
		
        //1. 0 ~ i ~ 1까지 탐색
		for (int j = 0; j < i; j++)
		{
        	//2. 최대 수열 길이 갱신
			if (arr[i] > arr[j])
			{
				maxNum = max(maxNum, dp[j]);
			}
		}
		
        //3. dp값 저장
		dp[i] = maxNum + 1;
	}

	for (int i = 1; i <= n; i++)
		maxNum = max(maxNum, dp[i]);

	return maxNum;
}

int main()
{
	cin >> n;

	for (int i = 1; i <= n; i++)
		cin >> arr[i];

	cout << solution();
}