1. 문제
1) 문제 링크
: www.acmicpc.net/problem/2631
2631번: 줄세우기
KOI 어린이집에는 N명의 아이들이 있다. 오늘은 소풍을 가는 날이다. 선생님은 1번부터 N번까지 번호가 적혀있는 번호표를 아이들의 가슴에 붙여주었다. 선생님은 아이들을 효과적으로 보호하기
www.acmicpc.net
2) 설명
문제 자체는 이해하기 쉽다. 간단하게 말하면 N명의 아이들이 무작위로 서있는데 얘네를 순서에 맞게 줄세우게 만드는 최소 이동 횟수를 구하면 된다. 예를 들어 1 4 2 3 6 7 5 이렇게 서있으면 1 2 3 4 5 6 7로 세우면 된다. 하지만 나는 푸는 데 오래 걸렸다..
2. 풀이
1) 알고리즘
: DP
2) 풀이 설명
LCS를 사용하면 풀이는 간단하다. 왜냐하면 가장 많이 정렬되어 있는 집단을 고르고 나머지만 옮기는 게 가장 적게 아이들을 이동시키며 줄세울 수 있는 방법이기 때문이다.
위에 예에서 1 2 3 6 7 이 LCS가 된다. 그러면 4, 5만 제자리 찾아서 옮겨주면 되니까 최소 이동 횟수는 2가 된다.
사실 LCS는 얼마 전에도 풀고 여러번 했었는데, 머리가 나빠선지 응용 문제가 나오니까 LCS가 생각도 안 났다.
한 이틀 정도 헛다리만 집었지만 다행이도 스스로 LCS를 생각해서 풀 수 있었다.
솔직히 LCS를 풀어본 경험이 있다면 굉장히 쉬운 문제라고 생각하지만 나는 이틀을 고민해서 찾아낸 만큼 기분이 아주 좋았다.
3. 코드
/*
줄 세우기
DP
*/
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int N;
cin >> N;
vector<int> children(N, 0), dp(N, 1);
for(int i=0;i<N;i++)
cin >> children[i];
for(int i=0;i<N;i++)
for(int j=i-1;j>=0;j--)
if(children[i] > children[j])
dp[i] = max(dp[i], dp[j] + 1);
cout << N - *max_element(dp.begin(), dp.end()) << "\n";
return 0;
}
4. 느낀점
1. 응용 문제를 자주 풀어보자!
'알고리즘 > 백준' 카테고리의 다른 글
[BOJ/14891] 톱니바퀴 (0) | 2020.12.18 |
---|---|
[백준/9656] 돌 게임 2 (0) | 2020.11.02 |
[백준/9252] LCS 2 (0) | 2020.10.27 |
[백준/11501] 주식 (0) | 2020.10.18 |
[백준/15312] 이름 궁합 (1) | 2020.10.18 |