C++/코드트리 챌린지
[코드트리 챌린지] 4주차 DP l - 조건에 맞게 선택적으로 전진하는 DP / 최대 증가 부분 수열
tmd1
2023. 10. 1. 19:07
https://www.codetree.ai/missions/2/problems/longest-increasing-subsequence/description
코드트리 | 코딩테스트 준비를 위한 알고리즘 정석
국가대표가 만든 코딩 공부의 가이드북 코딩 왕초보부터 꿈의 직장 코테 합격까지, 국가대표가 엄선한 커리큘럼으로 준비해보세요.
www.codetree.ai
코드:
#include <bits/stdc++.h>
using namespace std;
int n;
int arr[1005];
int dp[1005];
// dp[i]는 마지막으로 고른 원소가 i번째 일때
// 최대 증가 부분 수열을 말합니다.
void Initialize() {
// 모든 지점이 수열의 시작이 될 수 있으므로
// 모두 1로 초기화 합니다.
for (int i = 0; i < n; i++) {
dp[i] = 1;
}
}
int main(void) {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n;
for (int i = 0; i < n; i++) {
cin >> arr[i];
}
Initialize();
int maxCnt = INT_MIN; // 최대 증가 부분 수열 길이
for (int i = 1; i < n; i++) {
for (int j = 0; j < i; j++) {
// i번째 보다 앞에 있는 원소들 중
// arr[i] 보다 작은 값인 arr[j]를 찾고
// arr[j] 를 선택 했을 때의 최장 길이(dp[j]) + 1
// 한 값이 dp[i]가 됩니다.
if (arr[j] < arr[i]) {
dp[i] = max(dp[i], dp[j] + 1);
}
}
}
// 모든 dp를 탐색하여 가장 큰 값을 고릅니다.
for (int i = 0; i < n; i++) {
maxCnt = max(maxCnt, dp[i]);
}
cout << maxCnt;
}
n을 입력받고 0~n까지 arr 배열을 주어진 값으로 초기화합니다.
dp 배열의 경우 dp[i]는 마지막으로 선택한 원소가 i번째 일때 최장 길이 부분 수열을 뜻합니다.
그러므로 Initialize()함수를 통해 dp[i]를 모두 1로 초기화 해줍니다.
기본적으로 어느 부분이든 시작 위치가 될 수 있기 때문입니다.
그 이후 i 보다 작은 j를 통해 arr[j]를 살펴보면서 arr[i]보다 작은 값이 있는지 확인합니다.
만약 arr[j]가 arr[i]보다 작다면 dp[i]의 값은 arr[j]를 선택했을 때 최장 길이(dp[j]) + 1 이라고
할 수 있습니다.
즉 dp[i]의 점화식은 dp[i] = max(dp[j]+1) (0 <= j < n , arr[j] < arr[i]) 입니다.