728x90
$N \times N$으로 놓여진 동전을 한행씩, 한열씩 뒤집을 수 있을 때 T의 갯수를 최소화 하는 문제이다.
이 문제는 $2^N$ 완전탐색을 통한 전처리 후 나머지를 그리디하게 결정하는 방법으로 풀 수 있다.
각 행을 뒤집는 경우를 완전탐색으로 결정한다고 해보자.
각 행에 대해 뒤집을지 말지 결정하는 경우의 수를 $2^N$의 시간 복잡도로 찾을 수 있다.
각 행에 대해 뒤집는 연산이 끝나면 각 열에 대해 뒤집었을 때와 뒤집지 않을 때의 T의 개수를 비교하여 T가 더 적은 쪽을 선택해나가는 방식으로 답을 구할 수 있다.
행이 아니라 열을 뒤집는 경우에 수에 대해 탐색하고 각 행을 뒤집을지 결정해도 상관없다.
총 시간복잡도는 $O(2^NN^2)$ 가 된다.
전체 코드
더보기
#include <bits/stdc++.h>
using namespace std;
char field[20][20];
char mp[255];
int cnt = 1e9;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n;
(cin >> n).get();
mp['H'] = 'T', mp['T'] = 'H';
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < n; ++j)
field[i][j] = cin.get();
cin.get();
}
int bit = (1 << n) - 1;
while (bit)
{
char newfield[20][20];
copy(&field[0][0], &field[0][0] + 20 * 20, &newfield[0][0]);
int cmpcnt = 0;
for (int i = 0; i < n; ++i)
{
if (bit & (1 << i))
{
for (int j = 0; j < n; ++j)
newfield[i][j] = mp[newfield[i][j]];
}
}
for (int k = 0; k < n; ++k)
{
int front = 0, back = 0;
for (int s = 0; s < n; ++s)
{
if (newfield[s][k] == 'T')
++front;
else
++back;
}
if (front > back)
cmpcnt += back;
else
cmpcnt += front;
}
cnt = min(cnt, cmpcnt);
--bit;
}
cout << cnt;
}
728x90
'백준 > 그리디' 카테고리의 다른 글
[COCI] 백준 9935 - 문자열 폭발 (0) | 2020.11.15 |
---|---|
백준 14247 - 나무 자르기 (0) | 2020.08.13 |
백준 17420 - 깊콘이 넘쳐흘러 (0) | 2020.07.09 |
백준 1082 - 방 번호 (0) | 2020.07.08 |
백준 1080 - 행렬 (0) | 2020.06.21 |