Notice
250x250
Recent Posts
Recent Comments
Link
넘치게 채우기
[BOJ] 14002 : 가장 긴 증가하는 부분 수열 4 본문
728x90
반응형
https://www.acmicpc.net/problem/14002
문제 유형 : 다이나믹 프로그래밍 (동적 계획법)
문제 난이도 : Gold IV
문제
수열 A가 주어졌을 때, 가장 긴 증가하는 부분 수열을 구하는 프로그램을 작성하시오.
예를 들어, 수열 A = {10, 20, 10, 30, 20, 50} 인 경우에 가장 긴 증가하는 부분 수열은 A = {10, 20, 10, 30, 20, 50} 이고, 길이는 4이다.
입력
첫째 줄에 수열 A의 크기 N (1 ≤ N ≤ 1,000)이 주어진다.
둘째 줄에는 수열 A를 이루고 있는 Ai가 주어진다. (1 ≤ Ai ≤ 1,000)
출력
첫째 줄에 수열 A의 가장 긴 증가하는 부분 수열의 길이를 출력한다.
둘째 줄에는 가장 긴 증가하는 부분 수열을 출력한다. 그러한 수열이 여러가지인 경우 아무거나 출력한다.
풀이
현재까지의 배열 탐색에서 가장 긴 증가하는 부분 수열을 담는 2차원 배열 dp를 생성한다.
arr를 순회한다.
arr[i]를 추가로 뒤에 넣을 수 있는 부분 수열들 중에서 가장 긴 부분 수열에 자기 자신을 붙인 수열을 dp[i]에 저장한다.
(이 과정에서는 이전의 부분 수열들을 검사한다.)
만약에 조건에 맞는 수열이 없다면, 빈 수열에 자신이 첫 요소가 된다.
그럼 dp[0]부터 dp[n-1]까지 각각의 최대 긴 부분 수열이 저장되어 있다.
이 중에서 가장 긴 수열의 길이와 수열을 출력시키면 된다.
코드(C++)
#include <iostream>
#include <vector>
using namespace std;
int arr[1001];
int main()
{
int n;
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> arr[i];
}
vector<vector<int>> dp(n);
for (int i = 0; i < n; i++)
{
int maxSize = 0;
int prevIdx = -1;
for (int j = i - 1; j >= 0; j--)
{
if (arr[i] > arr[j] && dp[j].size() + 1 > maxSize)
{
maxSize = dp[j].size();
prevIdx = j;
}
}
if (maxSize != 0)
{
dp[i].assign(dp[prevIdx].begin(), dp[prevIdx].end());
}
dp[i].push_back(arr[i]);
}
int maxIdx = -1;
int maxLen = 0;
for (int i = 0; i < n; i++)
{
if (dp[i].size() > maxLen)
{
maxLen = dp[i].size();
maxIdx = i;
}
}
cout << maxLen << endl;
for (int i = 0; i < maxLen; i++)
{
cout << dp[maxIdx][i] << " ";
}
return 0;
}
728x90
반응형
'PS > BOJ' 카테고리의 다른 글
[BOJ] 다리 놓기 (0) | 2023.09.28 |
---|---|
[BOJ] 2023 : 신기한 소수 (0) | 2023.09.22 |
[BOJ] 1328 : 고층 빌딩 (0) | 2023.09.21 |
[BOJ] 16234 : 인구 이동 (0) | 2023.09.19 |
[BOJ] 15686: 치킨 배달 (0) | 2023.09.18 |