Algorithm/백준
[백준][11054번] 가장 긴 바이토닉 부분 수열
1일1코딩
2020. 3. 25. 22:58
https://www.acmicpc.net/problem/11054
11054번: 가장 긴 바이토닉 부분 수열
첫째 줄에 수열 A의 크기 N이 주어지고, 둘째 줄에는 수열 A를 이루고 있는 Ai가 주어진다. (1 ≤ N ≤ 1,000, 1 ≤ Ai ≤ 1,000)
www.acmicpc.net
풀이과정
부분 수열은 1, 2, 3, 2 1 과 같이 오름과 내림이 있는 수열을 말한다.
오름차순 수열과 내림차순 수열을 최대 길이를 구하여 문제를 풀었다.
오름차순은 dp[N] = dp[1]....dp[N-1] 중 map[N] 값 보다 작으면서 젤 긴 수열을 찾아 +1을 해주었다.
내림차순은 뒤에서 시작했다. 특정 K값에서 내림차순으로 수열을 정의해야 K값이 겹치기 때문이다.
이제 dp[K] + dp2[K] 값 중 최댓값을 찾아 -1을 해주면 된다. K위치에서 겹치기 때문에 -1을 해준다.
소스코드
더보기
#include <stdio.h>
int map[1001];
int dp[1001];
int dp2[1001];
int N;
int solution()
{
dp[0] = 1; //증가수열
dp2[N-1] = 1; //감소수열
int last = N - 1;
int answer = 1;
for (int i = 1; i < N; i++) {
dp[i] = dp2[last - i] = 1;
for (int j = 0; j < i; j++) {
if (map[j] < map[i] && dp[i] < dp[j] + 1) {
dp[i] = dp[j] + 1;
}
if (map[last - j] < map[last - i] && dp2[last - i] < dp2[last - j] + 1) {
dp2[last - i] = dp2[last - j] + 1;
}
}
}
for (int i = 0; i < N; i++) {
int tmp = dp[i] + dp2[i] - 1;
if (answer < tmp) {
answer = tmp;
}
}
return answer;
}
int main()
{
scanf("%d", &N);
for (int i = 0; i < N; i++) {
scanf("%d", &map[i]);
}
printf("%d\n", solution());
}