문제
수열 S가 어떤 수 Sk를 기준으로 S1< S2< ... Sk-1< Sk> Sk+1> ... SN-1> SN을 만족한다면, 그 수열을 바이토닉 수열이라고 한다.
예를 들어, {10, 20,30, 25, 20}과 {10, 20, 30,40}, {50, 40, 25, 10} 은 바이토닉 수열이지만, {1, 2, 3, 2, 1, 2, 3, 2, 1}과 {10, 20, 30, 40, 20, 30} 은 바이토닉 수열이 아니다.
수열 A가 주어졌을 때, 그 수열의 부분 수열 중 바이토닉 수열이면서 가장 긴 수열의 길이를 구하는 프로그램을 작성하시오.
입력
첫째 줄에 수열 A의 크기 N이 주어지고, 둘째 줄에는 수열 A를 이루고 있는 Ai가 주어진다. (1 ≤ N ≤ 1,000, 1 ≤ Ai≤ 1,000)
출력
첫째 줄에 수열 A의 부분 수열 중에서 가장 긴 바이토닉 수열의 길이를 출력한다.
구현
바이토닉 수열의 중점은
1. 앞에서 뒤로 부분 수열을 한 번 찾고
2. 뒤에서 앞으로 부분 수열을 한 번 찾은 후
3. 해당 배열값들의 합중 가장 큰 값을 찾는것이다.
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#define _CRT_SECURE_NO_WARNINGS
int compare(int a, int b) {
return (a > b) ? a : b;
}
int main(void) {
int num, i, j, result = 0, max = 0;
int arr[1001] = { 0 };
int dp1[1001] = { 0 };
int dp2[1001] = { 0 };
scanf("%d", &num);
for (i = 1; i <= num; i++) {
scanf("%d", &arr[i]);
}
for (i = 1; i <= num; i++) { //앞에서 뒤 가장 긴 증가하는 부분 수열 찾기
max = 0;
for (j = 0; j < i; j++) {
if (arr[i] > arr[j]) {
if (dp1[j] > max) {
max = dp1[j];
}
}
}
dp1[i] = max + 1;
}
for (i = num; i > 0; i--) { //뒤에서 앞으로 가장 긴 증가하는 부분 수열 찾기
max = 0;
for (j = num; j > i; j--) {
if (arr[i] > arr[j]) {
if (dp2[j] > max) {
max = dp2[j];
}
}
}
dp2[i] = max + 1;
}
for (i = 1; i <= num; i++) { // 각 dp배열을 앞에서 뒤로 탐색하면서
if (result < dp1[i] + dp2[i] - 1) { // 배열 값의 합산 - 1 이 가장큰 값 찾기
result = dp1[i] + dp2[i] - 1;
}
}
printf("%d", result);
}
'Algorithm > DP' 카테고리의 다른 글
1912번 연속합 BOJ 백준 C언어 (0) | 2020.08.26 |
---|---|
2565번 전깃줄 BOJ 백준 C언어 (0) | 2020.08.25 |
11053번 가장 긴 증가하는 부분수열 BOJ 백준 C언어 (0) | 2020.08.24 |
2156번 포도주 시식 BOJ 백준 C언어 (0) | 2020.08.07 |
10844번 쉬운 계단 수 BOJ 백준 C언어 (0) | 2020.08.07 |
댓글