ํฌ์ŠคํŠธ

LIS

LIS

๐Ÿ’ซ LIS


Longest Increasing Subsequence์ตœ์žฅ ์ฆ๊ฐ€ ๋ถ€๋ถ„ ์ˆ˜์—ด

DP๋กœ ํ’€ ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ.
์ˆ˜์—ด์—์„œ ๊ฐ€์žฅ ๊ธด ์ฆ๊ฐ€ ๋ถ€๋ถ„ ์ˆ˜์—ด์„ ์ฐพ๋Š” ๋ฌธ์ œ.

๐Ÿซง ์šฉ์–ด ์ •๋ฆฌ

๋ถ€๋ถ„ ์ˆ˜์—ด
= ์ˆ˜์—ด์˜ ์›์†Œ ์ค‘ ์ผ๋ถ€๋ฅผ ์„ ํƒํ•ด์„œ(ํ˜น์€ ์ œ๊ฑฐํ•ด์„œ) ๋งŒ๋“  ์ˆ˜์—ด
i.e. 1 2 3 4์—์„œ 1 3 4, 2 4 ๋“ฑ

์ฆ๊ฐ€ ๋ถ€๋ถ„ ์ˆ˜์—ด
= ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌ๋œ ๋ถ€๋ถ„ ์ˆ˜์—ด
i.e. 1 2 3 4, 3 5 7 9 ๋“ฑ

์ตœ์žฅ ์ฆ๊ฐ€ ๋ถ€๋ถ„ ์ˆ˜์—ด
= ๊ฐ€์žฅ ๊ธด ์ฆ๊ฐ€ ๋ถ€๋ถ„ ์ˆ˜์—ด

๐Ÿ’ซ ์•Œ๊ณ ๋ฆฌ์ฆ˜


LIS

๐Ÿซง O(N^2)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
const int MX = 1005;
int a[MX];
int d[MX];

int main()
{
	int n;
	cin >> n;

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

	int mxLen = 0;
	for (int i = 1; i <= n; i++)
	{
		int curA = a[i];
		int curDMax = 0;

		for (int j = 0; j < i; j++)
		{
			int tarA = a[j];
			int tarD = d[j];

			if (tarA < curA)
				if (tarD >= curDMax)
					curDMax = tarD;
		}

		d[i] = curDMax + 1;
		mxLen = max(mxLen, d[i]);
	}

	cout << mxLen;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int n;
cin >> n;

vector<int> a(n);
vector<int> d(n);

for (int i = 0; i < n; i++)
	cin >> a[i];

for (int i = 0; i < n; i++)
{
	d[i] = 1;
	
	for (int j = 0; j < i; j++)
		if (a[j] < a[i] && d[i] < d[j] + 1)
			d[i] = d[j] + 1;
}

cout << *max_element(d.begin(), d.end());

๐Ÿซง O(N log N)

O(N^2) ๋ฐฉ๋ฒ•์„ ์ตœ์ ํ™”ํ•˜์—ฌ O(N log N)์œผ๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

O(N^2) ๋ฐฉ๋ฒ•์€ ํ•ด๋‹น ์‹œ์ ์—์„œ ๊ฐ€์žฅ ๊ธด ์ฆ๊ฐ€ ๋ถ€๋ถ„ ์ˆ˜์—ด์˜ ๊ธธ์ด๋ฅผ ๊ณ„์‚ฐํ•˜๊ณ  ๊ฐฑ์‹ ํ•˜๋Š” ๋ฐฉ์‹์ด๋ผ๋ฉด,

O(N log N) ๋ฐฉ๋ฒ•์€ ํ•ด๋‹น ์‹œ์ ์—์„œ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ๊ฐ€์žฅ ๊ธด ์ฆ๊ฐ€ ๋ถ€๋ถ„ ์ˆ˜์—ด์„ ์ž์ฒด๋ฅผ ๋งŒ๋“ค์–ด ๊ฐฑ์‹ ํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.
O(N log N) ๋ฐฉ๋ฒ•์€ ํ•ด๋‹น ์‹œ์ ์—์„œ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ๊ฐ€์žฅ ๊ธด ์ฆ๊ฐ€ ๋ถ€๋ถ„ ์ˆ˜์—ด์„ ๋งŒ๋“ค์–ด ๊ฐฑ์‹ ํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.
์ตœ์ข… ๊ฒฐ๊ณผ๋ฌผ์ด lis๊ฐ€ ๋˜์ง€๋Š” ์•Š๋Š”๋‹ค, ์ตœ์ข… ๊ฒฐ๊ณผ๋ฌผ์˜ ๊ธธ์ด๊ฐ€ lis์˜ ๊ธธ์ด๊ฐ€ ๋œ๋‹ค.

์ด์ง„ ํƒ์ƒ‰ (lower_bound)๋ฅผ ์ด์šฉํ•˜์—ฌ,
ํ•ด๋‹น ์‹œ์ ์— ๋งŒ๋“ค์–ด์ง„ ์ฆ๊ฐ€ ๋ถ€๋ถ„ ์ˆ˜์—ด์˜ ๋งˆ์ง€๋ง‰ ๊ฐ’๋ณด๋‹ค ํฐ ๊ฐ’์ด ๋‚˜์˜ค๋ฉด ๊ทธ ๊ฐ’์„ ์ถ”๊ฐ€ํ•˜๊ณ ,
์ž‘์€ ๊ฐ’์ด ๋‚˜์˜ค๋ฉด lower_bound๋กœ ์ž‘์€ ๊ฐ’์ด ๋Œ€์ฒดํ•  ์ˆ˜ ์žˆ๋Š” ์œ„์น˜๋ฅผ ์ฐพ์•„ ๋Œ€์ฒดํ•œ๋‹ค.

(๋ญ”๊ฐ€ ์„ค๋ช…์ด ์ง๊ด€์ ์ด์ง„ ์•Š๋‹ค. ๊นŒ๋จน์—ˆ๋‹ค๋ฉด ์ฝ”๋“œ ๋ณด๋ฉด์„œ ์ดํ•ดํ•  ๊ฒƒ.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
int n;
cin >> n;

vector<int> a(n);
for (int i = 0; i < n; i++)
	cin >> a[i];

// ํ•ด๋‹น ์‹œ์ ์—์„œ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ๊ฐ€์žฅ ๊ธด ์ฆ๊ฐ€ ๋ถ€๋ถ„ ์ˆ˜์—ด, ๊ทธ ์ค‘์—์„œ ์š”์†Œ๋“ค์˜ ๊ฐ’์ด ๊ฐ€์žฅ ์ž‘์€ ์ˆ˜์—ด์„ ๋งŒ๋“ค์–ด ๋‚˜๊ฐ„๋‹ค.
vector<int> lis;
for (int i = 0; i < n; i++)
{
	// ์ด์ง„ ํƒ์ƒ‰์œผ๋กœ a[i]๋ณด๋‹ค ํฌ๊ฑฐ๋‚˜ ๊ฐ™์€ ๊ฐ’์ด ์žˆ๋Š”์ง€ ํ™•์ธ (๊ทธ ์ค‘ ๊ฐ€์žฅ ์™ผ์ชฝ์— ์žˆ๋Š” ๊ฐ’)
	// ์—ฌ๊ธฐ์„œ๋Š” ์ผ๋‹จ a[i]๋ณด๋‹ค ํฐ ๊ฐ’์„ ์ฐพ๊ณ , ๊ทธ๊ฑธ a[i] ๋Œ€์ฒดํ•˜๊ณ  ์‹ถ๋‹ค๋Š” ์ƒ๊ฐ
	auto it = lower_bound(lis.begin(), lis.end(), a[i]);

	// ์—†์œผ๋ฉด ๋’ค์— ์ถ”๊ฐ€
	if (it == lis.end())
	{
		lis.push_back(a[i]);
	}
	// ์žˆ์œผ๋ฉด ๊ทธ ๊ฐ’์„ a[i]๋กœ ๊ต์ฒด
	else
	{
		*it = a[i];

		// ๊ต์ฒดํ•˜๋Š” ์ด์œ ๋Š” ์ „์ฒด์ ์œผ๋กœ ์š”์†Œ๋“ค์˜ ๊ฐ’์ด ์ž‘์•„์•ผ ๋‚˜์ค‘์— ๋” ๊ธด ์ฆ๊ฐ€ ๋ถ€๋ถ„ ์ˆ˜์—ด์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์•„์ง€๊ธฐ ๋•Œ๋ฌธ
		
		// ์˜ˆ๋ฅผ ๋“ค์–ด 5 1 2๋ผ๋Š” ์ˆ˜์—ด์—์„œ, ๊ฐ ์š”์†Œ๋ฅผ ์ˆœํšŒํ•˜๋ฉฐ LIS๋ฅผ ๊ตฌํ•œ๋‹ค๊ณ  ๊ฐ€์ •
		// 5๊นŒ์ง€ ์ˆœํšŒ๋ฅผ ํ•˜๊ณ , (ํ˜„์žฌ LIS๋Š” {5})
		// 1๋ฅผ ์ˆœํšŒํ•˜๋Š” ์ฐจ๋ก€์—์„œ,
		
		// 5๋ฅผ 1๋กœ ๋ฐ”๊ฟ”๋„ ์–ด์ฐจํ”ผ ๊ธธ์ด๋Š” ๋˜‘๊ฐ™๋‹ค๊ณ  5๋ฅผ ๊ทธ๋Œ€๋กœ ๋‘๋ฉด ์ตœ์ข…์ ์œผ๋กœ LIS๋ฅผ {5}๋กœ ๋งŒ๋“ค ์ˆ˜ ๋ฐ–์— ์—†๋‹ค.
		// ์™œ๋ƒํ•˜๋ฉด 2๋Š” 5๋ณด๋‹ค ์ž‘์•„์„œ ๋ชป ๋“ค์–ด๊ฐ€๋‹ˆ๊นŒ.
		
		// ๋งŒ์•ฝ 5๋ฅผ 1๋กœ ๋ฐ”๊ฟจ๋‹ค๋ฉด, {1}๋กœ ์‹œ์ž‘ํ•˜๋Š” LIS๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ณ 
		// ๊ทธ ๋‹ค์Œ 2๋ฅผ ์ˆœํšŒํ•˜๋Š” ์ฐจ๋ก€์—์„œ, {1}์— 2๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด {1, 2}๋กœ LIS๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.
	}
}

cout << lis.size();

์ฃผ์„ ์—†๋Š” ์ฝ”๋“œ.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int n;
cin >> n;

vector<int> a(n);
for (int i = 0; i < n; i++)
	cin >> a[i];

vector<int> lis;
for (int i = 0; i < n; i++)
{
	auto it = lower_bound(lis.begin(), lis.end(), a[i]);
	if (it == lis.end())
	{
		lis.push_back(a[i]);
	}
	else
	{
		*it = a[i];
	}
}

cout << lis.size();

๐Ÿ’ซ ๊ธฐ๋ก


๐Ÿ’ซ ๋ฌธ์ œ


์ด ๊ธฐ์‚ฌ๋Š” ์ €์ž‘๊ถŒ์ž์˜ CC BY 4.0 ๋ผ์ด์„ผ์Šค๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค.