본문 바로가기
Algorithm/DFS, BFS, 백트래킹

섹션 6. 수열 추측하기

by brother_stone 2022. 10. 17.


순열라이브러리와 DP를 통해 이항계수를 구한 풀이법

from itertools import permutations

n, f = map(int, input().split())

tri = [[1] * 11 for _ in range(11)]
tri[2][1] = 2
cnt = 0
for i in range(3, 11):
    for j in range(1, i):
        cnt += 1
        tri[i][j] = tri[i - 1][j - 1] + tri[i - 1][j]

b = tri[n - 1]
b = b[:n]
seq = list(range(1, n + 1))

for v in permutations(seq):
    seq = list(v)
    res = 0
    for i in range(n):
        res += seq[i] * b[i]

    if res == f:
        print(*seq)
        break

 

DFS를 이용한 풀이

n, f = map(int, input().split())


def dfs(l, sum):
    if l == n and sum == f:
        print(*p)
        exit()

    for i in range(1, n + 1):
        if not ch[i]:
            ch[i] = 1
            p[l] = i
            dfs(l + 1, sum + (p[l] * b[l]))
            ch[i] = 0


p = [0] * n
b = [1] * n

for i in range(1, n - 1):
    b[i] = b[i - 1] * (n - i) // i

ch = [0] * (n + 1)

dfs(0,0)

가장 밑의 줄에 있는 수 F는 구해야 하는 수열에서 이항계수만큼 곱해야 구할 수 있다는 것을 알아채야 풀 수 있는 문제였다. 

문제에서 주어진 예시를 보자. 구해야 하는 수열은 3 1 2 4 인데 F=16은 \(3 * 1 + 1 * 3 + 2 * 3 + 4 * 1 \)의 결과값으로 수열에 곱한 계수는 각각 \( {}_3 C_0 \\~\\ {}_3 C_1 \\~\\ {}_3 C_2 \\~\\ {}_3 C_3 \\~\\\)과 같다. 즉,  N-1일 때의 이항계수와 같다.

 

따라서 n이 주어지면 n에 해당하는 이항계수 리스트를 만들어서 F와 같은 값이 나올 때까지 모든 수열의 경우의 수와 곱하는 게 핵심 로직이 되겠다.

 

앞으로 파스칼의 삼각형을 이용한 문제(두개를 더한 값 이용)가 나오면 이항계수로 풀 수 있는 지 생각해보자

'Algorithm > DFS, BFS, 백트래킹' 카테고리의 다른 글

[Java] 백준 15683 - 감시  (0) 2023.06.19
[Java]백준 1260 - DFS와 BFS  (0) 2023.04.20
섹션 7. 휴가  (0) 2022.10.19
섹션 6. 순열 구하기  (0) 2022.10.17
이진트리 순회(DFS)  (0) 2022.10.08