# 백준 : 부분집합의 합(1182)
문제
https://www.acmicpc.net/problem/1182소스
(Github: https://github.com/wonjnlee/wallydev/blob/master/bj_1182_sumofparts)#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <cstring>
#include <list>
#include <cmath>
using namespace std;
int N, S;
int cnt, sum;
long long int numbers[21];
int visit[21];
void DFS(int v) {
if(v == N) return;
if((sum + numbers[v]) == S) cnt++;
DFS(v + 1); // not add
sum += numbers[v];
DFS(v + 1);
sum -= numbers[v];
}
int main(void)
{
cin>>N>>sum;
for(int i=0; i<N; i++) cin>>numbers[i];
DFS(0);
cout<<cnt<<endl;
return 0;
}
풀이
백트래킹이라는 기법에 대한 공부를 진행하고 있는데, 가장 기초적인 문제라고 해서 풀어보았다.실제 DFS, BFS에 대한 개념이 바로 기억나지 않아서 좀 놀라긴 했는데..
덕분에 백트래킹 공부하면서 DFS, BFS 공부도 할 수 있어서 좋았다.
백트래킹은 DFS를 기반으로 해서 '모든 원소를 다 훑어보는' 일종의 브루트포스 형식을 의미한다.
몇가지 다른점을 이야기해보면
1. DFS에서 접점의 방문 유무를 확인하기 위해 사용하던 visit과 같은 내용을 사용하지 않는다
본 문제에서도 원하는 합의 유무를 확인하기 때문에, 합을 기준으로 접점 방문 유무를 따졌다.
2. 맨 마지막에 '접점을 방문하지 않은 척' 해야 한다.
사실 이부분이 제일 헷갈렸는데, 결국 검사할건 다 하고 검사하지 않은 척 해야한다는 말이다.
조금 유하게 표현하면, '다음 녀석들이 또 검사해볼 수 있도록 깨끗하게 정리하는 과정'이라고 보면 되겠다.
말은 이렇게 했지만 실제 코드 작성중에는 생각하지도 못했고, 또 참고사이트를 봐도 이부분을 이해하는게 어려웠다는...
댓글
댓글 쓰기