https://www.acmicpc.net/problem/2450
최소한으로 이동하는 방법을 생각해 내지 못했다..
정렬이 이뤄지면 결과적으로 6개의 가능한 모양이 있다. (1,2,3의 순열)
이 때 최소한으로 움직이는 방법을 살펴보면
1. 그룹(1)에 있는 그룹(2)(3)에 속해야 하는 요소들의 개수 (그룹(2),(3)에 속한 그룹(1)요소의 개수와 같다)
(ex 입력이 1223111, (1,2,3)순서라면 2+1)
2. 그룹(2)에 있는 그룹(3)요소의 개수, 그룹(3)에 있는 그룹(2) 요소의 개수; 둘 중 큰 것
1,2를 더해주면 최소한으로 움직이는 횟수가 된다.
복잡해보이지만, 그룹1먼저 채워주고 그룹2,3을 생각해주는 것이다.
생각하는 과정에서 스쳐가듯 생각한 방법이긴 하지만, 이 방법이 유효하지 않은 경우가 있을 것 같아서 제꼈다. 푼 사람들 중에 이 논리를 검증한 사람이 있을까? 아니면 검증하지 않아도 당연한 논리인걸까?
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int INF = 1e9;
vector<int> vec;
int cnt[4], p[3] = { 1,2,3 };
int main() {
int n; cin >> n;
for (int i = 0, input; i < n; i++) {
cin >> input;
vec.push_back(input);
cnt[input]++;
}
int mn = INF;
do {
int arr[4][4] = { 0 }; //p[i]번 위치의 j의 개수
int sp = 0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < cnt[p[i]]; j++)
arr[p[i]][vec[sp + j]]++;
sp += cnt[p[i]];
}
mn = min(mn, arr[1][2]+arr[1][3]+max(arr[2][3],arr[3][2]));
} while (next_permutation(p, p+3));
cout << mn << '\n';
}
arr를 채워주는 논리를 짜는 것도 쉽지만은 않았다.
mn 갱신하는 부분에서 arr[p[1]][p[2]]로 하지않고 1,2,3 숫자로 고정한 이유는 조금만 생각해 보면 될 것이다.
(그룹만 잘 나눠줬다면 위에 설명한 논리에 들어가는 숫자 순서를 바꿔도 되기 떄문. 그룹2부터채우고 1,3을 채운다던지)
'알고리즘 > 백준 & swacademy' 카테고리의 다른 글
BOJ 1701 - Cubeeditor (KMP, 실패함수) (0) | 2019.11.06 |
---|---|
SW 8568 - 3으로 나눈 순열 (발상) (0) | 2019.11.03 |
BOJ 14863 - 서울에서 경산까지 ( KOI 초등, knapsack ) (0) | 2019.10.15 |
BOJ 10835 - 카드게임 ( 2015 KOI 초등, dp ) (0) | 2019.10.14 |
BOJ 10834 - 벨트( KOI 초, 오버플로우 ) (0) | 2019.10.14 |