기록공간

반도체 설계 (백준 - 2352번) 본문

Algorithm/문제

반도체 설계 (백준 - 2352번)

입코딩 2020. 2. 19. 20:38
반응형

 

동적계획법(Dynamic Programming)을 사용하여 가장 긴 최장증가수열(LIS)을 구하는 문제이다.

 

동적계획법 : https://lipcoder.tistory.com/49

 

동적계획법(Dynamic Programming)

동적계획법 이란? 동적계획법(다이나믹 프로그래밍)은 큰 문제를 작은 문제로 나누어 푸는 알고리즘 방법이다. 다이나믹 프로그래밍이란 명칭은 그냥 알고리즘 창조한 사람이 단지 이름이 멋지다는 이유로 붙여진..

lipcoder.tistory.com

최장증가수열 : https://lipcoder.tistory.com/50

 

최장증가수열 - LIS(Longest Increasing Subsequence)

LIS(최장증가수열)는 동적계획법으로 풀 수 있는 알고리즘 문제 중 하나이다. 어떤 임의의 수열이 주어졌을때, 이 수열에서 몇 개의 수들을 제거해서 부분수열을 만들수 있다. 이 때 만들어진 부분수열 중 오름차..

lipcoder.tistory.com

 

하지만 시간제한이 존재하기 때문에 시간복잡도가 O(n^2)이 나오는 알고리즘을 쓰면 시간 초과가 나온다. 그래서 각 원소마다 그 원소의 이전 값들을 쭉 훑어보며 LIS를 찾는 알고리즘은 쓸 수 없다. 

 

해결법은 이전 값들을 찾을때 이진탐색을 사용하여 O(nlogn)의 시간복잡도를 가지도록 구현하는 것이다. 

 

코드는 다음과 같다.

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

int main()
{
	int input = 0;
	cin >> input;

	// 이전 값들을 저장할 벡터
	vector<int> vt;
	vt.push_back(0);
    
	int* list = new int[input + 1];
	list[0] = 0;
	for (int i = 1; i <= input; ++i)
	{
		cin >> list[i];
	}

	int max = 0;
	for (int i = 1; i <= input; ++i)
	{
		int length = 0;
		// 만약 원소가 이전 값들보다 큰 경우
		if (vt.back() < list[i])
		{
			// LIS를 구하고 원소를 벡터에 추가한다.
			length = (vt.size() - 1) + 1;
			vt.push_back(list[i]);
		}
		//  원소가 크기상 벡터 사이에 들어가는 경우
		else
		{
			// 이진 탐색을 이용하여 원소에 알맞은 위치를 찾는다.
			auto iter = lower_bound(vt.begin(), vt.end(), list[i]);
			// 위치 정보를 활용하여 LIS를 구한다.
			int dist = distance(vt.begin(), iter);
			length = (dist - 1) + 1;
			// 그 위치에 원소를 현재 원소값으로 덮어쓴다.
			vt[dist] = list[i];
		}
		if (max < length)
			max = length;
	}

	cout << max << endl;
	delete[] list;
}
반응형

'Algorithm > 문제' 카테고리의 다른 글

1, 2, 3 더하기 (백준 - 9095번)  (0) 2020.02.20
1로 만들기 (백준 - 1463번)  (0) 2020.02.20
행렬 (백준 - 1080번)  (0) 2020.02.19
부등호 (백준 - 2529번)  (0) 2020.02.19
기타줄 (백준 - 1049번)  (0) 2020.02.13
Comments