[백준 11053번 C/C++] 가장 긴 증가하는 부분 수열

 

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

 


 

 

해결전략

 

최대 증가길이 수열

Longest Increasing Subsequence, LIS

Dynamic Programming (DP) 다이나믹 프로그래밍

 

 


 

코드

 

#include <iostream>
#include <vector>
using namespace std;

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);

	int n, res;
	cin >> n;
	vector<int> v(n), dp(n);

	for (int i = 0; i < n; i++) {
		cin >> v[i];
	}

	dp[0] = 1;
	res = 1;
	for (int i = 1; i < n; i++) 
	{
		int prevDpMax = 0;

		for (int j = i - 1; j >= 0; j--)
		{
			if (v[j] < v[i] && dp[j] > prevDpMax)
			{
				prevDpMax = dp[j];
			}
		}

		dp[i] = prevDpMax + 1;

		if (res < dp[i]) res = dp[i];
	}

	cout << res;

	return 0;
}

 

 


 

코드 해설

 

#include <iostream>
#include <vector>
using namespace std;

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);

	int n, res;
	cin >> n;

	//주어진 값을 넣는 v, 각 숫자의 최대부분 증가 길이를 기록하는 dp
	vector<int> v(n), dp(n);

	for (int i = 0; i < n; i++) {
		cin >> v[i];
	}

	dp[0] = 1;//첫 숫자의 최대부분 증가 길이는 무조건 1이다.
	res = 1;//n=1인 경우 dp[0]이 최대부분 증가 길이이기 때문에 1이다.

	for (int i = 1; i < n; i++) 
	{
		int prevDpMax = 0;

		// i-1 ~ 0까지 탐색. 
		for (int j = i - 1; j >= 0; j--)
		{
			// v[i]의 숫자보다 작은 숫자들 중 최대부분 증가 길이가 prevDpMax보다 큰 경우
			// max값이 0으로 시작해서 계속해서 큰 값으로 갱신된다. 
			// 결국에 해당 if조건에서 가장 큰 dp[j]값이 prevDpmax값이 된다. 
			if (v[j] < v[i] && dp[j] > prevDpMax)
			{
				prevDpMax = dp[j];
			}
		}

		//dp[i]보다 작은 숫자에서 가질 수 있는 최대부분 증가 길이(위에서 설정한 prevDpMax)에서 +1 해준다. 뒤에 i번째 위치한 숫자를 배치한다는 개념이다.
		dp[i] = prevDpMax + 1;

		//i번째 최대부분 증가 길이가 가장 큰 값인지 검사하고 가장 큰 값이면 res값을 dp[i]로 갱신한다.
		if (res < dp[i]) res = dp[i];
	}

	cout << res;

	return 0;
}