※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 24834번 문제인 Shortest and Longest LIS이다.
문제는 아래 링크를 확인하자.
https://www.acmicpc.net/problem/24834
24834번: Shortest and Longest LIS
For each test case, print two lines with $n$ integers each. The first line is the sequence with the minimum length of the LIS, and the second line is the sequence with the maximum length of the LIS. If there are multiple answers, print any one of them. Eac
www.acmicpc.net
1이상 N이하의 서로 다른 수로 이루어지고, 서로 인접한 두 수의 대소 관계가 주어진 문자열과 같은 길이 N의 수열 중 LIS의 길이가 가장 짧은 수열과 긴 수열을 각각 구하는 문제이다.
주어지는 문자열에 '<'가 연속으로 최대 k회 이어지는 부분이 존재한다면(없다면 k=0으로 한다) 적어도 해당 부분에 대응되는 k+1개의 연속한 항은 증가수열을 이루게 된다. 이것이 이 수열의 LIS(중 하나)가 되게끔 항상 수열을 구성할 수 있을지를 생각해보는 것으로 Shortest LIS를 갖는 수열을 찾아낼 수 있을 것이다.
주어지는 문자열에 등장하는 '<'의 개수를 m개라 하자. 이 때 LIS의 길이는 m+1보다 커질 수 없다는 것을 쉽게 알 수 있다. 여기서, LIS의 길이가 m+1인 수열을 항상 구성할 수 있을지를 생각해보는 것으로 Longest LIS를 갖는 수열을 찾아낼 수 있을 것이다.
위와 같은 방식으로 길이의 bound를 먼저 찾아낸다면 정답에 해당하는 수열 중 하나를 찾아내는 방법은 어렵지 않게 생각해낼 수 있다.
아래는 제출한 소스코드이다.
#include <iostream>
#include <string>
using namespace std;
void solve() {
int slen; string s; cin >> slen >> s;
// minLIS
int mx = slen;
int cnt = 1;
int tmp;
for (auto l : s) {
if (l == '<') cnt++;
else {
mx -= cnt;
tmp = mx + 1;
while (cnt--) cout << tmp++ << ' ';
cnt = 1;
}
}
mx -= cnt;
tmp = mx + 1;
while (cnt--) cout << tmp++ << ' ';
cout << '\n';
//maxLIS
int mn = 0;
cnt = 1;
for (auto l : s) {
if (l == '>') cnt++;
else {
mn += cnt;
tmp = mn;
while (cnt--) cout << tmp-- << ' ';
cnt = 1;
}
}
mn += cnt;
tmp = mn;
while (cnt--) cout << tmp-- << ' ';
cout << '\n';
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
int T; cin >> T;
while (T--) solve();
}
'BOJ' 카테고리의 다른 글
[BOJ 24927 // C++] Is It Even? (0) | 2022.04.02 |
---|---|
[BOJ 24833 // C++] Air Conditioner (0) | 2022.04.01 |
[BOJ 24832 // C++] Longest Palindrome (0) | 2022.03.30 |
[BOJ 24724 // C++] 현대모비스와 함께하는 부품 관리 (0) | 2022.03.29 |
[BOJ 24819 // C++] Escape Wall Maria (0) | 2022.03.28 |