https://www.acmicpc.net/problem/11054
해당 문제는 다이나믹 프로그래밍 문제로, LIS 문제를 응용하여 푸는 문제이다.
최장 바이토닉 부분 수열은 특정 인덱스에서의 최장 증가 수열과 최장 감소 수열을 합친 것의 최대값이라고 볼 수 있다.
ex. 수열 {50 10 20 30 25 20}의 최장 바이토닉 부분 수열은
1) nums
에 수열을 입력받아 저장하고, nums2
에 입력 받은 수열을 역순으로 저장한다.
2) 배열 dp1
, dp2
를 선언하고, 각각을 차례대로 갱신한다.
3) i가 0 ~ n일 때
(dp1[i]와 dp2[n - i + 1]의 합 - 1)을 구해 maxValue
와 비교한다.
만약 위 수가 maxValue
보다 크다면 maxValue
를 위 수로 갱신한다.
4) 최종적으로 maxValue
에 최장 바이토닉 부분 수열의 길이가 저장된다.
#include <iostream>
#include <algorithm>
using namespace std;
int nums[1001];
int nums2[1001];
int dp1[1001];
int dp2[1001];
int solution(int n)
{
for (int i = 1; i <= n; i++)
{
for (int j = 1; j < i; j++)
{
if (nums[i] > nums[j] && dp1[j] + 1 > dp1[i])
dp1[i] = dp1[j] + 1;
if (nums2[i] > nums2[j] && dp2[j] + 1 > dp2[i])
dp2[i] = dp2[j] + 1;
}
}
int maxValue = 0;
for (int i = 0; i <= n; i++)
{
int sum = dp1[i] + dp2[n - i + 1] - 1;
if (maxValue < sum)
maxValue = sum;
}
return maxValue;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr); cout.tie(nullptr);
int n;
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> nums[i];
nums2[n - i + 1] = nums[i];
dp1[i] = 1;
dp2[i] = 1;
}
cout << solution(n);
}