DFS, BFS 활용 - 0808. 수열 추측하기(DFS)
private static int n, m, C[][], nums[], coms[], answer[];
private static int combination(int n, int r) {
if(n == r || r == 0) return 1;
if(r == 1) return n;
if(C[n][r] == 0) C[n][r] = combination(n-1, r-1) + combination(n-1 , r);
return C[n][r];
}
private static boolean DFS(int L) {
if (L == n) {
int sum = 0;
for(int i=0; i<n; i++) sum += coms[i] * answer[i];
if(sum == m) return true;
} else {
for (int i = 0; i < nums.length; i++) {
if (nums[i] == 0) {
answer[L] = i + 1;
nums[i] = 1;
if(DFS(L+1)) return true;
nums[i] = 0;
}
}
}
return false;
}
private static void solution() {
nums = new int[n];
coms = new int[n];
answer = new int[n];
for(int i=0; i<=n-1; i++) {
coms[i] = combination(n-1, i);
}
DFS(0);
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
m = sc.nextInt();
C = new int[n+1][n+1];
solution();
for(int i : answer) System.out.print(i + " ");
}
static int[] b, p, ch;
static int n, f;
boolean flag=false;
int[][] dy=new int[35][35];
public int combi(int n, int r){
if(dy[n][r]>0) return dy[n][r];
if(n==r || r==0) return 1;
else return dy[n][r]=combi(n-1, r-1)+combi(n-1, r);
}
public void DFS(int L, int sum){
if(flag) return;
if(L==n){
if(sum==f){
for(int x : p) System.out.print(x+" ");
flag=true;
}
}
else{
for(int i=1; i<=n; i++){
if(ch[i]==0){
ch[i]=1;
p[L]=i;
DFS(L+1, sum+(p[L]*b[L]));
ch[i]=0;
}
}
}
}
public static void main(String[] args){
Main T = new Main();
Scanner kb = new Scanner(System.in);
n=kb.nextInt();
f=kb.nextInt();
b=new int[n];
p=new int[n];
ch=new int[n+1];
for(int i=0; i<n; i++){
b[i]=T.combi(n-1, i);
}
T.DFS(0, 0);
}
해당 문제는 DFS
를 이용하여 풀 수 있다. 우선 문제의 규칙을 살펴보자.
n
번 째 줄의 수열 추측하기 : 규칙
n
번 째 줄(가장 윗줄)에는 1
부터 n
까지, n
개의 수가 등장한다.n
번 째 수열과 { }을 차례로 곱한 값이 삼각형의 가장 아래 값이 같다.문제에 제시된 이미지의 예로 4번 째 줄에 등장하는 수열 { 3
, 1
, 2
, 4
}와 { }을
차례로 곱한 값을 살펴보면, 3 1 2 4 이다.
따라서 해당 문제를 풀기 위해서는 n
번 째 줄에 등장하는 조합 { }을 구하고,
1
부터 n
까지 수열을 나열하는 경우의 수를 순회하며, 서로 곱한 값을 확인한다.
나의 풀이에서는 coms
배열에 조합의 결과를 보관하도록 하고, nums
배열을 이용하여 인덱스에
해당하는 숫자의 사용 여부를 구분하도록 했다. 이후 DFS
를 수행하며 answer
배열에 나열할 수
있는 경우의 수를 보관하였다.
모든 수가 나열됐을 때 answer
와 coms
배열의 곱을 확인하여 정답을 반환하도록 구현했다.
강의 또한 동일한 로직으로 구성됐다.