컴퓨터 사이언스/1고리즘

백준 2352 : 반도체 설계

저세상 개발자 2021. 8. 19. 03:20

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

 

2352번: 반도체 설계

첫째 줄에 정수 n(1 ≤ n ≤ 40,000)이 주어진다. 다음 줄에는 차례로 1번 포트와 연결되어야 하는 포트 번호, 2번 포트와 연결되어야 하는 포트 번호, …, n번 포트와 연결되어야 하는 포트 번호가 주

www.acmicpc.net

 

줄이 꼬이지 않기 위해선 연결하는 줄의 번호가 증가하는 수열로 이루어지면 되므로 LIS로 풀 수 있는 문제다.

다만 일반적인 LIS는 O(n^2)의 시간복잡도를 갖는데, 이 문제의 경우 포트가 최대 4만개이므로 n^2은 시간 초과가 발생한다. O(nlogn)의 시간복잡도를 갖는 LIS는 아래와 같이 그리디 기법으로 구현할 수 있다.

 

#include <iostream>
#include <algorithm>

#define max(a,b) a>b?a:b
using namespace std;

int n;
int arr[40'000];
int lis[40'000];

int LIS() {
	int idx = 0, target;
	lis[0] = arr[0];
	for (int i = 1; i < n; i++) {
		//현재 포트가 가장 최근에 연결한 포트 번호보다 커서 줄이 꼬이지 않는 경우
		if (lis[idx] < arr[i]) {
			lis[++idx] = arr[i];
		}
		//줄이 꼬이는 경우 이전에 연결한 포트를 재조정
		//현재 포트 번호보다 큰 값들 중 가장 작은 값을 현재 포트 번호로 바꿔줌
		//-> 줄이 꼬이지 않는 한도 내에서 최고의 선택
		else {
			target = lower_bound(lis, lis + idx, arr[i]) - lis;
			lis[target] = arr[i];
		}
	}
	return idx + 1;
}

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

	cout << LIS();
}

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

	return 0;
}
메모리: 2332 kb 시간: 4 ms

 

nlogn 풀이는 아래 블로그를 참고했다.

https://jaimemin.tistory.com/488

 

백준 2352번 반도체 설계

문제 링크입니다: https://www.acmicpc.net/problem/2352 http://jaimemin.tistory.com/430와 유사한 문제로 LIS 문제였습니다. 하지만 기존의 문제는 O(n^2) 안에 풀어도 되는 문제였지만 이번 문제는 O(nlogn)..

jaimemin.tistory.com

https://dyngina.tistory.com/16

 

LIS (Longest Increasing Subsequence)

오랫만에 포스팅을 해보네요. 시험기간 (정확히 말하면 시험보는 기간입니다.) 이 되니까 별게 다 하고 싶어지네요. 이번에는 DP중에서 특별히 LIS에 대한 내용을 다뤄보려고 합니다. LIS. Longest Inc

dyngina.tistory.com