재귀는 항상 어려운 것 같다. 이해도 이해지만 이 풀이 방식을 기억해 놓는 것도 좋을 것 같다.
다 풀어놓고 실수 한 점은 팀이 3,3 으로 나뉘었을 때 (0,1) (0,2) (1,2) 등등 모든 순서쌍을 고려 해야 하는데 그러지 않았다. 모든 순서쌍을 더할 수 있는 코드로 고치니 풀이에 성공했다.
vector find, 조합, 백트래킹, DFS 를 통해 풀이했다.
재귀 풀이
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int N;
int mindiff = 99999999;
int arr[20][20];
int ans[10];
vector<int> v1, v2;
int cal(vector<int> v) {
int sum = 0;
for (int i = 0; i < v.size(); i++) {
for (int j = i + 1; j < v.size(); j++) {
sum += arr[v[i]][v[j]] + arr[v[j]][v[i]];
}
}
return sum;
}
void func(int depth,int next)
{
if (depth >= N / 2)
{
v2.clear();
for (int i = 0; i < N; i++) {
if (find(v1.begin(), v1.end(), i) == v1.end()) {
v2.push_back(i);
}
}
mindiff = min(mindiff, abs(cal(v1) - cal(v2)));
return;
}
for (int i = next; i < N; i++)
{
v1.push_back(i);
func(depth + 1, i + 1);
v1.pop_back();
}
}
int main()
{
cin >> N;
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
cin >> arr[i][j];
}
}
func(0, 0);
cout << mindiff;
return 0;
}
비트마스크 풀이
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int N;
int arr[20][20];
int ans = 9999999999;
vector<int> t1;
vector<int> t2;
int main()
{
cin >> N;
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
cin >> arr[i][j];
}
}
for (int i = 0; i < (1 << N); i++)
{
t1.clear();
t2.clear();
for (int k = 0; k < N; k++)
{
if (i & (1 << k))
{
t1.push_back(k);
}
else
{
t2.push_back(k);
}
}
if (t1.size() > N / 2 || t2.size() > N / 2) continue;
int sum1 = 0;
int sum0 = 0;
for (int a = 0; a < N / 2; a++)
{
for (int b = 0; b < N / 2; b++)
{
sum1 += arr[t1[a]][t1[b]];
sum0 += arr[t2[a]][t2[b]];
}
}
ans = min(ans, abs(sum1 - sum0));
}
cout << ans;
return 0;
}
'프로그래밍 공부 > 백준 (C++)' 카테고리의 다른 글
[C++ / 백준 1248번] Guess(맞춰봐) (0) | 2025.02.05 |
---|---|
[C++ / 백준 2529번] 부등호 (0) | 2025.01.13 |
[C++ / 백준 1759번] 암호 만들기 (0) | 2025.01.05 |
[C++ / 백준 10972번] 다음 순열 (0) | 2024.12.29 |
[ C++ / 백준 15663번 ] N과 M (9) (0) | 2024.12.28 |