BOJ 32944 잘못된 LIS 알고리즘
sorohue가 PS하는 블로그
BOJ 32944 잘못된 LIS 알고리즘
문제 링크입니다.
문제 요약
스탈린 소트로 LIS를 찾는 알고리즘을 저격하세요. 구체적으로, 수열의 길이가 $N$, LIS의 길이가 $M$, 위의 알고리즘으로 찾은 증가 수열의 길이가 $K < M$인 수열을 제시하세요.
풀이
$N = M$인 경우 저격이 불가능합니다. LIS의 길이가 $N$인 게 이미 오름차순인 수열밖에 없는데 이러면 그리디하게 돌려도 맞는 값이 나와서 그래요.
하지만 나머지 경우는 항상 저격이 가능함을 알 수 있습니다. 방법은 다음과 같습니다.
- 길이가 $K-1$인 증가수열 $[1,2,\cdots,K-1]$을 생각합시다.
- 그 뒤에 $N$을 추가합니다. 저격할 알고리즘에서 이 뒤의 원소는 싹 다 무시되므로 길이 $K$의 증가 수열이 얻어집니다.
- 이제 $K$부터 $M-1$까지의 원소를 나열해 LIS의 길이를 $M-1$로 만들어 줍니다.
- 그 뒤의 어느 원소를 골라도 그 원소가 LIS의 끝이도록, $N-1$부터 $M$까지의 원소를 내림차순으로 나열합니다.
이러한 방법으로 총 시간 복잡도 ${\cal O}(N)$에 문제를 해결할 수 있습니다.
코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
using pll = pair<ll, ll>;
int main(){
cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
int n, m, k; cin >> n >> m >> k;
if(m == n) return !(cout << -1);
for(int i = 1; i < k; i++) cout << i << ' ';
cout << n << ' ';
for(int i = k; i < m; i++) cout << i << ' ';
for(int i = n-1; i >= m; i--) cout << i << ' ';
}
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.