티스토리 뷰
반응형
문제
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을 만족한다면, 그 수열을 바이토닉 수열이라고 한다.
- 주어진 수열에서 길이가 최대가 되는 바이토닉 부분 수열을 찾는다.
해결 전략
- LIS
가 양쪽으로 있는 문제이다.
- 처음에는 기분 인덱스 i를 옮겨가며 양쪽에서 LIS
를 계산해 답을 도출하려고 하였다. 하지만 이렇게 되면 i를 움직이는 for문이 하나 더 생겨 결국 O(N^3)
이 되었다. N값이 아주 크지 않더라도 되도록이면 반복문을 줄이는 방향으로 코드를 작성해야한다.
코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
from sys import stdin
input = stdin.readline
N = int(input())
N_list = list(map(int, input().split()))
rev_list = N_list[::-1]
cache = [1] * N
cache2 = [1] * N
for i in range(1, N):
for j in range(i):
if N_list[i] > N_list[j]:
cache[i] = max(cache[i], cache[j]+1)
if rev_list[i] > rev_list[j]:
cache2[i] = max(cache2[i], cache2[j]+1)
cache2 = cache2[::-1]
for i in range(N):
cache[i] += cache2[i]-1
print(max(cache))
# 시간초과 코드
from sys import stdin
input = stdin.readline
N = int(input())
N_list = list(map(int, input().split()))
def lis(lst, cache):
for i in range(1, len(lst)):
for j in range(i):
if lst[i] > lst[j]:
cache[i] = max(cache[i], cache[j]+1)
return cache[len(lst)-1]
dp = [0] * (N)
for i in range(N): # 바이토닉의 중심 정하기
cache = [1]*(i+1)
cache2 = [1]*(N-i)
forward = lis(N_list[:i+1], cache)
backward = lis(N_list[i:][::-1], cache2)
dp[i] = forward + backward - 1
print(max(dp))
|
cs |
해설
- 아래에서 3중 for문의 속도 이슈가 발생하므로 위의 코드는 3중 for문을 2중, 단일 for문으로 분리하여 연산했다. 왼쪽부터 오른쪽으로 LIS를 풀고, 오른쪽에서 왼쪽으로 LIS를 푸는데 이를 이중 for문 한번으로 처리하기 위해 reverse해서 연산하였다.
새로 학습한 것 & 실수
- 처음에는 문제를 잘못 이해해서 부분 수열이 아니라 연속된 바이토닉을 찾았다. 문제가 너무 쉬워 이상했다.
반응형
'알고리즘 학습 > 백준 알고리즘' 카테고리의 다른 글
백준 알고리즘 - 제곱수의 합 (1699) [Python] (0) | 2020.09.21 |
---|---|
백준 알고리즘 - 연속합 (1912) [Python] (0) | 2020.09.21 |
백준 알고리즘 - 포도주 시식 (2156) [Python] (0) | 2020.09.20 |
백준 알고리즘 - 이친수 (2193) [Python] (0) | 2020.09.20 |
백준 알고리즘 - 오르막수 (11057) [Python] (0) | 2020.09.20 |
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 랜선자르기#이분탐색#BOJ#Python
- API#lazy#
- django
- 텀 프로젝트#백준알고리즘#Python
- 병든 나이트#BOJ#탐욕법#Python
- 순열사이클#BOJ#Python
- 토마토#백준알고리즘#Python
- Triangle#Sorting#Codility#Python
- django#slicing
- 날짜 계산#BOJ#완전탐색#Python
- filter#isalnum#lower
- 미로 탐색#백준알고리즘#Python
- 리모컨#완전탐색#BOJ#Python
- 터틀비치#리콘#xbox#controller
- NumberofDiscIntersections#Codility#Sort#Python
- PassingCars#Codility#Python
- Distinct#Codility#Python
- 섬의개수#백준알고리즘#Python
- Swift#Tuples#Range
- 반복수열#백준알고리즘#Python
- 배열합치기#분할정복#BOJ#Python
- 암호코드#dp#BOJ#Python
- 파이썬알고리즘인터뷰#4장
- 종이자르기#분할정복#BOJ#Python
- 백준 알고리즘#BackTracking
- 쿼드트리#BOJ#분할정복#Python
- Brackets#Stacks and Queues#Codility#Python
- N으로 표현#DP#Programmers#Python
- 공유기 설치#BOJ#이분탐색#Python
- 나무자르기#BOJ#이분탐색#Python
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
글 보관함