프로그래밍 공부/백준 (C++)
[C++ / 백준 1182번] 부분 수열의 합
Rocketbabydolls
2025. 2. 19. 11:29
문제
시행 착오
비트마스크 사용법을 몰라 인터넷에 검색해 이해했다. 비트 연산을 통해 백트래킹 사용을 하거나 큰 크기의 배열을 선언할 필요 없이 간편하게 해결할 수 있었다.
비트마스크는 아래 글을 읽고 이해했다.
[알고리즘] | 비트마스크
비트마스크란? > 컴퓨터는 내부적으로 모든 자료를 이진수(비트)로 처리한다. 이런 컴퓨터의 연산방식을 이용한, 정수의 이진수 표현을 활용하여 문제를 해결하는 기법을 말한다. 비트(Bit)란? 비
velog.io
비트마스크 풀이의 좋은 점은 O(1) 시간에 계산이 가능하다는 점이다. 실행 시간이 빨라지고 메모리도 적게 사용하며, 집합을 이용해 0부터 1<<N -1 까지의 경우의 수를 비트연산을 이용해 전부 체크해볼 수 있다. 어떤 문제에서는 백트래킹보다 효율적인듯 하다.
해결 방법
비트마스크 사용 X (백트래킹만 사용)
#include <iostream>
using namespace std;
int N, S, cnt = 0;
int s[21];
void recur(int ind, int cursum)
{
if (ind == N) // 종료 조건: 모든 원소를 탐색했을 때
{
if (cursum == S) cnt++;
return;
}
// 현재 원소를 선택하는 경우
recur(ind + 1, cursum + s[ind]);
// 현재 원소를 선택하지 않는 경우
recur(ind + 1, cursum);
}
int main() {
cin.tie(NULL);
ios::sync_with_stdio(false);
cin >> N >> S;
for (int i = 0; i < N; i++)
cin >> s[i];
recur(0, 0);
// 공집합 제거 (S == 0일 때, 아무것도 선택하지 않은 경우 포함됨)
if (S == 0) cnt--;
cout << cnt;
return 0;
}
비트마스크 사용
#include <iostream>
using namespace std;
int N, S, cnt = 0;
int s[20];
int main() {
cin.tie(NULL);
ios::sync_with_stdio(false);
cin >> N >> S;
for (int i = 0; i < N; i++)
cin >> s[i];
for (int i = 1; i < (1 << N); i++)
{
int sum = 0;
for (int j = 0; j < N; j++)
{
if (i & (1 << j))
{
sum += s[j];
}
}
if (sum == S)
{
cnt++;
}
}
cout << cnt;
return 0;
}