※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※

 

이번에 볼 문제는 백준 16132번 문제인 그룹 나누기 (Subset)이다.
문제는 아래 링크를 확인하자.

https://www.acmicpc.net/problem/16132

 

\(N\)개의 수의 총합은 \(N(N+1)/2\)와 같고, 이 값이 홀수이면 두 부분집합의 각각의 원소의 합이 같게끔 집합을 분할할 수 없어 답은 0이 된다. 아래에서는 이 값이 짝수인 경우만을 생각할 것이다. 이 경우, 두 집합 각각의 원소의 합은 \(N(N+1)/4\)와 같게 된다.

 

주어진 수들을 적절히 골라 그 합이 정확히 \(N(N+1)/4\)가 되게끔 하는 경우의 수는 knapsack DP를 이용해 간단하게 구할 수 있다. \(N\)의 값이 충분히 작으므로 탐색해야 하는 범위 \(N(N+1)/4\)와 총 수의 개수 \(N\)의 값이 작기 때문이다.

 

한편, 위에서 구한 경우의 수는 정확히 두 개씩 짝을 이루어 두 부분집합을 구성하는 경우의 수를 이루므로, 위에서 구한 경우의 수에 2를 나눈 값이 문제의 답이 된다. 이를 이용해 문제를 해결하는 코드를 작성하자.

 

아래는 제출한 소스코드이다.

#include <iostream>
using namespace std;
typedef long long ll;

int N, NN;
ll dp[1276];

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);

	cin >> N;
	NN = N * (N + 1) / 2;
	if (NN & 1) {
		cout << 0;
		return 0;
	}
	NN /= 2;
	dp[0] = 1;
	for (int i = 1; i <= N; i++) {
		for (int k = NN; k >= i; k--) {
			dp[k] += dp[k - i];
		}
	}
	cout << dp[NN] / 2;
}
728x90

'BOJ' 카테고리의 다른 글

[BOJ 23352 // C++] 방탈출  (4) 2024.07.23
[BOJ 16203 // C++] 까다로운 수 찾기  (0) 2024.07.22
[BOJ 12065 // C++] gMatrix (Large)  (0) 2024.07.20
[BOJ 8478 // C++] Chessboard  (0) 2024.07.19
[BOJ 24649 // C++] Letters Q and F  (0) 2024.07.18

+ Recent posts