📌 문제 출처: BOJ 11054 - 가장 긴 바이토닉 부분 수열
제목
( 7/29 - class3 : 백준11054 )
문제 유형
- 다이나믹 프로그래밍 (DP)
- 가장 긴 증가하는 부분 수열 (LIS)
- 가장 긴 감소하는 부분 수열 (LDS)
- 바이토닉 수열 (Bitonic Sequence)
풀이 방법 도출
- 각 인덱스를 기준으로 좌우로 증가/감소하는 LIS를 모두 구함
- dpL[i]: 왼쪽에서 i까지 증가하는 LIS 길이
- dpR[i]: 오른쪽에서 i부터 감소하는 LIS 길이
- 최종 결과는 dpL[i] + dpR[i] - 1의 최대값- 중복된 i를 두 번 세지 않기 위해 -1
 
시간 복잡도
- LIS + LDS 각각 O(N²)
- 전체 시간 복잡도: O(N²) (N ≤ 1000이므로 충분히 가능)
코드
#include <bits/stdc++.h>
using namespace std;
#define X first
#define Y second
using ll = long long;
int main(void) {
  ios::sync_with_stdio(0);
  cin.tie(0);
  int n;
  cin >> n;
  vector<int> a(n), dpL(n, 1), dpR(n, 1);
  for(int i=0;i<n;i++) cin >> a[i];
  // dpL LIS forward
  for(int i=0;i<n;i++) {
    for(int j=0;j<i;j++) {
      if(a[j] < a[i]) dpL[i] = max(dpL[i], dpL[j]+1);
    }
  }
  // dpR LDS backwards
  for(int i=n-1;i>=0;i--) {
    for(int j=n-1;j>i;j--) {
      if(a[j] < a[i]) dpR[i] = max(dpR[i], dpR[j]+1);
    }
  }
  int res = 0;
  for(int i=0;i<n;i++)
    res = max(res, dpL[i] + dpR[i] - 1);
  cout << res;
}
 
      
댓글남기기