https://www.acmicpc.net/problem/11053
가장 긴 감소하는 부분 수열의 반대 문제되겠다.
당시에는 몰랐는데 꽤 여러곳에 응용되는 전형적인 알고리즘인 것 같다.
문제에서 주어진 예시를 활용해서 아이디어를 좀 더 깔끔하게 정리해보자.
10 20 10 30 20 50
위와 같은 예시가 주어졌다.
먼저 10까지만 봤을 때는, 부분 수열의 길이는 1이다.
이제 20을 확인해보자. 초기에 20을 확인하면, 수열의 성분은 20하나이기때문에 길이는 1이다.
즉 d[]의 초기값은 모두 1이라고 할 수 있다.
이제 10과 비교해서 확인해보자. 10은 20보다 작기때문에 기본적으로 증가 수열의 조건을 만족한다.
또 한가지 확인해야 할 것은, 10에 20을 연결했을때, 기존에 20과 연결되어있는 다른 수열보다 길이가 길겠느냐 하는 것을 생각해 보는 것이다.
20까지만 확인한 경우, 이전에 나온 성분이 10밖에 없기 때문에 다소 모호하게 보일 수 있겠다.
일단 d[1]의 값은 2이다. (10과 20이 증가 수열을 이루기 때문에)
다음으로 10을 살펴보자. 초기에 10 자체로 수열을 이룬다고 볼 수 있기 때문에 앞서 언급한 것처럼 초기값은 1이다.
이제 가장 앞의 10과 비교해보자. 10은 10과 이어져서 증가 수열을 이룰 수 없다. 마찬가지로 20과도 이어질 수 없다. 따라서 d[2] = 1이 되겠다.
다음으로 30을 살펴보자. 30에 대해서 10을 먼저 비교해보면, 30은 10과 이어서 증가 수열이 될 수 있다. 따라서 10과 함께 증가 수열을 이룬다고 할 때, d[3] = 2가 되겠다.
20과 비교해보자. 20은 10과 연결되어서 증가 수열을 이룰 수 있다고 앞에서 확인했었다. 그렇다면 30을 연결하면?
길이가 3이된다. 30은 현재 10과 연결해서 길이 2의 부분 증가 수열을 이루고 있었는데, 20과 연결된다면 길이가 증가할 수 있다. 따라서 20과 연결되어서 길이가 3이된다. d[2] = 3이 된다.
이런 흐름의 알고리즘을 활용하면 된다.
'알고리즘 문제 풀이 > 백준 온라인 저지' 카테고리의 다른 글
백준 2178번 미로 탐색 (C++) (0) | 2019.08.24 |
---|---|
백준 1158번 조세퍼스 문제 (C++) (0) | 2019.08.24 |
백준 17140번: 이차원 배열과 연산 (C++) (0) | 2019.08.23 |
백준 15684번: 사다리 조작 (C++) (0) | 2019.08.23 |
백준 16637번: 괄호 추가하기 (C++) (0) | 2019.08.21 |