[Silver II] 가장 긴 증가하는 부분 수열 - 11053
성능 요약
메모리: 2028 KB, 시간: 0 ms
분류
다이나믹 프로그래밍(dp)
문제 설명
수열 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의 가장 긴 증가하는 부분 수열의 길이를 출력한다.
첫번째 틀린 풀이
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
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
vector <pair<int, int>> series;
int n;
int cnt = 1;
int max = 0;
cin >> n;
int a;
for (int i = 0; i < n; i++)
{
cin >> a;
series.push_back({ a,i });
}
if (n == 1) {
cout << 1;
return 0;
}
sort(series.begin(), series.end());
int check=0;
int q;
for (int i = 0; i < series.size(); i++)
{
q = i;
for (int j = i + 1; j < series.size(); j++)
{
if (series[q].first < series[j].first && series[q].second < series[j].second) {
cnt++;
q=j;
}
if (max < cnt)
max = cnt;
}
cnt = 1;
}
cout << max;
return 0;
}
반례
10
1 3 2 1 4 5 2 3 7 10
-> 5
ans-> 6
왜 틀린가 했더니 바로 뒤에 있는 숫자만 비교를 해서 틀린거였다,,
맞은풀이
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
#include <iostream>
using namespace std;
int A[1002];
int dp[1002];
int main() {
ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
int N;
cin >> N;
for (int i = 1; i <= N; i++) {
cin >> A[i];
}
int max_length = 1;
for (int i = 1; i <= N; i++)
{
dp[i] = 1;
for (int j = 1; j < i; j++)
{
if (A[i] > A[j])
{
dp[i] = max(dp[i], dp[j] + 1);
}
}
if (dp[i] > max_length) {
max_length = dp[i];
}
}
cout << max_length;
return 0;
}
A[i]>A[j] 일때
점화식 => dp[i]=max(dp[i],dp[j]+1)이 된다.