728x90

http://www.acmicpc.net/problem/11054

 

11054번: 가장 긴 바이토닉 부분 수열

첫째 줄에 수열 A의 크기 N이 주어지고, 둘째 줄에는 수열 A를 이루고 있는 Ai가 주어진다. (1 ≤ N ≤ 1,000, 1 ≤ Ai ≤ 1,000)

www.acmicpc.net

 

 

# 조건

  • 수열 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)
 

# 접근 방법

  • dp를 이용해주면 된다.
  • 2중 for문을 통해 모든 수에 대해 가장 긴 증가하는 수열을 찾아주면 될 것 같다.
  • O(1000^2) 이므로 제한 시간 1초안에 가능하다.
  • 이 때, 정방향으로 1번, 역 방향으로 1번을 구한 후 같은 index의 값을 더한 후 -1 해주면 된다.
  • 즉 기준 인덱스의 왼쪽 -> 증가하는 수열
  • 오른쪽 -> 감소하는 수열을 구한다고 생각하면 된다.

이 때, 감소하는 수열의 dp 값을 구한 후 뒤집어 주어야 하는 것에 주의!!

import sys  
sys.stdin = open('input.txt')  
input = sys.stdin.readline  
  
  
  
N = int(input())  
arr = [*map(int, input().split())]  
arr2 = arr[::-1]  
dp = [1] * N  
dp2 = [1] * N  
  
for i in range(N):  
    for j in range(i):  
        if arr[i] > arr[j]:  
            dp[i] = max(dp[i], dp[j] + 1)  
  
        if arr2[i] > arr2[j]:  
            dp2[i] = max(dp2[i], dp2[j] +1)  
  
dp2.reverse()  
result = max(dp[i] + dp2[i] - 1 for i in range(N))  
print(result)
728x90