๋ฐฑํธ๋ํน(Backtracking) ์๊ณ ๋ฆฌ์ฆ
์ ์กฐ๊ฑด์ ๋ง์กฑํ๋ ํด๋ฅผ ์ฐพ๊ธฐ ์ํด์ ์ ํ ๊ฐ๋ฅํ ๋ชจ๋ ๊ฒฝ์ฐ์ ์๋ฅผ ์๋ํ๋ฉฐ, ์ ํํ ๊ฒฝ๋ก๊ฐ ํด๊ฒฐ์ฑ ์ผ๋ก ์ด์ด์ง์ง ์์ผ๋ฉด ์ด์ ๋จ๊ณ๋ก ๋์๊ฐ์ ๋ค๋ฅธ ๊ฒฝ๋ก๋ฅผ ์๋ํ๋ ์๊ณ ๋ฆฌ์ฆ์ ๋๋ค.
์ผ๋ฐ์ ์ผ๋ก ๋ฐฑํธ๋ํน ์๊ณ ๋ฆฌ์ฆ์ ๊น์ด ์ฐ์ ํ์(DFS, Depth First Search)์ ๊ธฐ๋ฐ์ผ๋ก ํฉ๋๋ค.
- ์ ์ฝ ์กฐ๊ฑด์ ๋ง์กฑํ๋ ๋ชจ๋ ํด๋ฅผ ์ฐพ๋ ๊ฒ์ด ๋ชฉํ์ ๋๋ค.
- ๊ฐ๋ฅํ ๋ชจ๋ ๊ฒฝ์ฐ์ ์๋ฅผ ์๋ํ๋ฉฐ, ์ผ๋จ ํด๊ฒฐ์ฑ ์ผ๋ก ์ด์ด์ง์ง ์์ผ๋ฉด ์ด์ ๋จ๊ณ๋ก ๋์๊ฐ์ ๋ค๋ฅธ ๊ฒฝ์ฐ๋ฅผ ์๋ํฉ๋๋ค.
- ๋ฌธ์ ์ ํฌ๊ธฐ๊ฐ ์ปค์ง์๋ก ๋ถํ์ํ ๊ณ์ฐ์ด ๋ง์์ง๊ธฐ ๋๋ฌธ์, ์ ์ ํ
๊ฐ์ง์น๊ธฐ(pruning) ๊ธฐ๋ฒ
์ด ํ์ํฉ๋๋ค. - ๋ฐฑํธ๋ํน์ ๋ถํ์ํ ํ์์ ํ์ง ์๋ ๋ถ๋ถ์์, ๋ชจ๋ ๊ฒฝ์ฐ์ ์๋ฅผ ํ์ํ๋
DFS ์๊ณ ๋ฆฌ์ฆ
๊ณผ๋ ์ฐจ์ด์ ์ด ์์ต๋๋ค.
โป ๊ฐ์ง์น๊ธฐ๋ฅผ ์ผ๋ง๋ ์ํ๋๋์ ๋ฐ๋ผ ํธ์จ์ฑ์ด ๊ฒฐ์ ๋ฉ๋๋ค.
Backtrack(x)
if x is not a solution
return false
if x is a new solution
add to list of solutions
backtrack(expand x)
ํ์ด
์ด ๋ฌธ์ ๋ n๊ฐ์ ์์ฐ์ ์ค์์ ์ค๋ณต ์์ด m๊ฐ๋ฅผ ๊ณ ๋ฅด๋ ๋ชจ๋ ๊ฒฝ์ฐ๋ฅผ ์ถ๋ ฅํ๋ ๋ฌธ์ ์ ๋๋ค.
combinations ํจ์
๋ฅผ ์ฌ์ฉํ์ฌ ์กฐํฉ์ผ๋ก ์ฝ๊ฒ ํ์ด๊ฐ ๊ฐ๋ฅํ์ง๋ง,
๋ฐฑํธ๋ํน
์ ์ด์ฉํ์ฌ ์ฝ๋๋ฅผ ์์ฑํด๋ณด๊ฒ ์ต๋๋ค.
n, m = map(int, input().split())
def backtracking(selected, depth):
# ๊ฐ์๊ฐ m๊ณผ ๊ฐ์ผ๋ฉด ์ถ๋ ฅ
if depth == m:
print(' '.join(map(str, selected)))
return
# ํ์ฌ๊น์ง ์ ํํ ์ซ์๋ค ์ค ๊ฐ์ฅ ํฐ ์ซ์๋ณด๋ค ํฐ ์ซ์๋ค๋ง ์ ํ
start = selected[-1] + 1 if selected else 1
for i in range(start, n+1):
backtracking(selected + [i], depth + 1)
backtracking([], 0)