https://www.acmicpc.net/problem/1285
1285번: 동전 뒤집기
첫째 줄에 20이하의 자연수 N이 주어진다. 둘째 줄부터 N줄에 걸쳐 N개씩 동전들의 초기 상태가 주어진다. 각 줄에는 한 행에 놓인 N개의 동전의 상태가 왼쪽부터 차례대로 주어지는데, 앞면이 위
www.acmicpc.net
풀이가 떠오르지 않아 다른 블로그를 참고하였던 문제이다.
핵심은 독립 시행이다.
바로 행을 뒤집는 것과 열을 뒤집는 것이 서로 영향을 끼치지 않기 때문이다.
주어진 제한은 1 <= N <= 20 이므로 모든 열 또는 행에 대해서 최대 2 ^ 20 만큼의 계산으로 경우를 구할 수 있다(뒤집거나 안 뒤집거나).
만약 행에 대해서 모든 경우를 구하였다면, 각 경우마다 열을 살펴보기만 하면 최솟값을 구할 수 있다.
즉, O(N^2 * 2^N) = 약 3억으로 6초의 시간제한을 가뿐하게 통과할 수 있다.
#include <iostream>
#include <vector>
using namespace std;
int n;
vector<vector<char>> a(20, vector<char>(20));
int main() {
cin >> n;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> a[i][j];
}
}
int ans = 1000000000;
for (int i = 0; i < (1 << n); i++) { //행에 대해 모든 경우의 수를 탐색
vector<vector<char>> t = a;
for (int j = 0; j < n; j++) {
if (i & (1 << j)) {
for (int k = 0; k < n; k++) {
if (t[j][k] == 'H')t[j][k] = 'T'; //임시 배열에 행을 뒤집어준다.
else t[j][k] = 'H';
}
}
}
int tot = 0;
for (int i1 = 0; i1 < n; i1++) {
int cnt = 0;
for (int j = 0; j < n; j++) {
if (t[j][i1] == 'T')cnt++; //열을 탐색하며 뒤집었을 경우 H가 되는 개수를 센다.
}
if (cnt > n - cnt) {
tot += n - cnt;
}
else tot += cnt;
}
ans = min(ans, tot);
}
cout << ans;
}
Reference
'ps' 카테고리의 다른 글
[백준] 1103 - 게임 (0) | 2022.07.27 |
---|---|
[백준] 1194 - 달이 차오른다, 가자. (0) | 2022.07.26 |
[백준] 2613 - 숫자구슬 (0) | 2022.07.26 |
[백준] 7570 - 줄 세우기 (0) | 2022.07.25 |
[백준] 2873 - 롤러코스터 (0) | 2022.07.25 |
댓글