거의 알고리즘 일기장

알고스팟 _ LIS, 백준 12015번 _가장 긴 증가하는 부분 수열 2 본문

알고리즘 문제풀이

알고스팟 _ LIS, 백준 12015번 _가장 긴 증가하는 부분 수열 2

건우권 2020. 5. 8. 15:09

https://www.algospot.com/judge/problem/read/LIS

 

algospot.com :: LIS

Longest Increasing Sequence 문제 정보 문제 어떤 정수 수열에서 0개 이상의 숫자를 지우면 이 수열의 부분 수열 (subsequence) 를 얻을 수 있다. 예를 들어 10 7 4 9 의 부분 수열에는 7 4 9, 10 4, 10 9 등이 있다. 단, 10 4 7 은 원래 수열의 순서와 다르므로 10 7 4 9 의 부분 수열이 아니다. 어떤 부분 수열이 순증가할 때 이 부분 수열을 증가 부분 수열 (increasing subseque

www.algospot.com

 O(n^2) 풀이

 

 반복문 풀이

#include <iostream>
#include <algorithm>

using namespace std;
int N;
int dp[501];
int arr[501];

void Input()
{
	cin >> N;
	for (int i = 0; i < N; i++)
	{
		cin >> arr[i];
	}
}

void solve()
{
	int maxValue = 1;

	for (int i = 0; i < N; i++)
	{
		int value = arr[i];
		dp[i] = 1;
		for (int j = i; j >= 0; j--)
		{
			if (value > arr[j])
				dp[i] = max(dp[i], dp[j] + 1);
		}
		maxValue = max(maxValue, dp[i]);
	}
	cout << maxValue << '\n';
}

int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	int testcase;
	cin >> testcase;
	for (int i = 0; i < testcase; i++)
	{
		Input();
		solve();
	}
	return 0;
}

 

 재귀방식 풀이

#include <iostream>
#include <algorithm>

using namespace std;
int N;
int dp[501];
int arr[501];

void dpInit()
{
	for (int i = 0; i < N; i++)
		dp[i] = -1;
}

void Input()
{
	cin >> N;
	for (int i = 0; i < N; i++)
	{
		cin >> arr[i];
	}
}

int solve(int start)
{
	int& ret = dp[start];
	if (ret != -1)	return ret;

	ret = 1;
	for (int next = start + 1; next < N; next++)
		if(arr[start] < arr[next])
			ret = max(ret, solve(next) + 1);
	return ret;
}

int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	int testcase;
	cin >> testcase;
	for (int i = 0; i < testcase; i++)
	{
		Input();
		dpInit();
		int maxValue = 0;
		for (int j = 0; j < N; j++)
			maxValue = max(maxValue, solve(j));
		cout << maxValue << '\n';
	}
	return 0;
}

 

 O(nlogn)  풀이 

 이 문제는 백준 문제임.

https://www.acmicpc.net/problem/12015

 

12015번: 가장 긴 증가하는 부분 수열 2

첫째 줄에 수열 A의 크기 N (1 ≤ N ≤ 1,000,000)이 주어진다. 둘째 줄에는 수열 A를 이루고 있는 Ai가 주어진다. (1 ≤ Ai ≤ 1,000,000)

www.acmicpc.net

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int n; // 벡터의 길이
vector <int> arr_a;

int main()
{
	cin >> n;
	arr_a.push_back(0);
	int tmp = 0;
	for (int i = 0; i < n; i++)
	{
		cin >> tmp;
		if (arr_a.back() < tmp)
		{
			arr_a.push_back(tmp);
		}
		else
		{
			int index = lower_bound(arr_a.begin(), arr_a.end(), tmp) - arr_a.begin();
			arr_a[index] = tmp;
		}
	}

	cout << arr_a.size() - 1;

	return 0;
}

 후기

반응형
Comments