0. [c++] 백준 |
https://www.acmicpc.net/problem/11054
1. 풀이 |
바이토닉 증가 수열은 2가지의 조건을 만족시켜야 한다.
N개의 입력을 받은 arr[N] 배열이 존재한다고 생각하자.
이때, arr[k] (k는 N보다 작거나 같은 임의의 정수이다)를 기준으로 바이토닉 부분 수열을 만든다면, 앞은 계속해서 감소하는 형태여야 하고, 뒤로는 계속해서 커져야 할 것이다.
이를 활용하고, 추가적으로 메모이제이션을 활용해서 계산을 단축시켜주었다.
2. 소스코드 |
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 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | #include<iostream> #include<algorithm> #include<vector> using namespace std; typedef unsigned long long ull; //int cache[1001]; int decrease[1001]; int increase[1001]; int arr[1001]; int N; //int dp(int start, int here, int left, int right) { // int& ret = cache[start]; // if (ret != 0) // return ret; // ret = 1; // for (int next = here + 1; next < N; next++) { // if (arr[left] < arr[next]) // ret = max(ret, dp(next) + 1); // } // // return ret; //} int calcDecrease(int here) { int& ret = decrease[here]; if (ret != 0) return ret; ret = 1; for (int i = here + 1; i < N; i++) { if (arr[here] > arr[i]) { ret = max(ret, 1 + calcDecrease(i)); } } return ret; } int calcIncrease(int here) { int& ret = increase[here]; if (ret != 0) return ret; ret = 1; for (int i = here - 1; i >= 0; i--) { if (arr[here] > arr[i]) { ret = max(ret, 1 + calcIncrease(i)); } } return ret; } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cin >> N; for (int i = 0; i < N; i++) { cin >> arr[i]; } for (int i = 0; i < N; i++) { calcDecrease(i); calcIncrease(i); } int ret = 0; for (int i = 0; i < N; i++) { ret = max(ret, increase[i] + decrease[i] - 1); } cout << ret; return 0; } | cs |
3. 참고 |
질문이나 지적 있으시면 댓글로 남겨주세요~
도움 되셨으면 하트 꾹!
728x90
반응형
'<백준> > |c++| easy' 카테고리의 다른 글
[c++] 백준 11653 - 소인수분해(수학) (0) | 2019.08.22 |
---|---|
[c++] 백준 1037 - 약수(수학) (0) | 2019.08.22 |
[c++] 백준 11053 - 가장 긴 증가하는 부분 수열(동적 계획법) (0) | 2019.08.10 |
|c++| 백준 10814 - 나이순 정렬 (0) | 2019.07.28 |
|c++| 백준 11651 - 좌표 정렬하기 2(정렬) (2) | 2019.07.28 |