일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- java
- Graph
- Javascript
- 안드로이드
- BFS
- 리트코드
- Redux
- 프로그래머스
- frontend
- network
- 다이나믹 프로그래밍
- DFS
- db
- DP
- TypeScript
- Algorithm
- 자바
- 백준
- Python
- 동적 계획법
- git
- VIM
- Database
- react
- LeetCode
- vscode
- Data Structure
- 그레이들
- 알고리즘
- CS
Archives
- Today
- Total
늘 겸손하게
문제 11054 가장 긴 바이토닉 부분 수열 ( C++ ) 본문
문제 풀이
dp를 이용하여 오름차순으로 증가하는 부분 수열 중 가장 긴 수열의 길이를 찾고, 내림차순으로 감소하는 부분 수열 중 가장 긴 수열의 길이를 찾은 뒤 두 값을 합하고, -1을 해서 출력하면 풀 수 있는 문제이다.
1. 입력 받기
그냥 받아도 상관없지만 속도를 증가시키면서 입력을 받아보자
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
세 줄로 입력을 조금이라도 빠르게 받을 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
int main (void) {
ios_base::sync_with_stdio(false); cin.tie(NULL);
cout.tie(NULL);
int n;
cin >> n;
for (int i = 1; i <= n ;i++)
cin >> arr[i];
solve(n);
return 0;
}
|
cs |
2.오름차순 부분수열 구하기
front_dp[i]에 저장된 원소값은 해당 인덱스값에서 시작된 부분수열의 최대 길이를 저장한다. 부분 수열의 최소 길이는 1이므로 (자기 자신만을 원소로 가질 때) front_dp[i]의 초기값은 1이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
for (int i = 1 ; i <= n ; i++)
{
front_dp[i] = 1;
for (int j = 1 ; j <= i ; j++ )
{
if ( arr[j] < arr[i] && front_dp[i] < front_dp[j] + 1 )
{
front_dp[i] = front_dp[j] + 1;
}
}
}
|
cs |
3. 내림차순 부분수열 구하기
오름차순 부분수열과 비슷하다.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
for (int i = n ; i >= 1 ; i--)
{
back_dp[i] = 1;
for (int j = n; j >= i ; j--)
{
if ( arr[i] > arr[j] && back_dp[j] + 1 > back_dp[i] )
{
back_dp[i] = back_dp[j] + 1;
}
}
}
|
cs |
4. 최대 길이 구하기
오름차순 부분수열 최장 길이, 내림차순 부분수열 최장 길이를 합한 값에 1을 빼야한다. 1을 빼는 이유는 중앙값이 중복되기 때문.
예로, { 1, 2, 3 } , { 3, 2, 1} 이라면 3이 겹치므로 최장 길이 합에 1을 빼야함
1
2
3
4
5
6
7
8
9
10
|
int ans = 0;
for (int i = 0; i <= n ; i++ )
{
if ( ans < front_dp[i] + back_dp[i] - 1 )
ans = front_dp[i] + back_dp[i] - 1;
}
cout << ans << endl;
|
cs |
코드
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
#include <iostream>
using namespace std;
int arr[1001];
int front_dp[1001];
int back_dp[1001];
void solve(int n) {
for (int i = 1 ; i <= n ; i++) {
front_dp[i] = 1;
for (int j = 1 ; j <= i ; j++ ) {
if ( arr[j] < arr[i] && front_dp[i] < front_dp[j] + 1 ) {
front_dp[i] = front_dp[j] + 1;
}
}
}
for (int i = n ; i >= 1 ; i--) {
back_dp[i] = 1;
for (int j = n; j >= i ; j--) {
if ( arr[i] > arr[j] && back_dp[j] + 1 > back_dp[i] ) {
back_dp[i] = back_dp[j] + 1;
}
}
}
int ans = 0;
for (int i = 0; i <= n ; i++ )
{
if ( ans < front_dp[i] + back_dp[i] - 1 )
ans = front_dp[i] + back_dp[i] - 1;
}
cout << ans << endl;
}
int main (void) {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int n;
cin >> n;
for (int i = 1; i <= n ;i++)
cin >> arr[i];
solve(n);
return 0;
}
|
cs |
결과
'코딩 문제 > 백준' 카테고리의 다른 글
백준 12865 - 평범한 배낭 (C++) (0) | 2021.08.31 |
---|---|
백준 11660 - 구간 합 구하기 5 (0) | 2021.08.30 |
백준 1932 - 정수 삼각형 (C++) (0) | 2021.08.16 |
백준 1158 요세푸스 문제 ( C++ ) (0) | 2021.08.11 |
백준 18870 ( C++ ) (0) | 2021.08.10 |