문제 요약
문제 링크: https://www.acmicpc.net/problem/27533
토끼 부부 토순이와 토준이가 N×M 격자에서 (1,1)에서 출발하여 (N,M)으로 이동합니다. 두 토끼는:
- 오른쪽과 아래쪽으로만 이동
- 동시에 한 칸씩 이동
- 출발점과 도착점을 제외하고 중간에 만나지 않음
이러한 조건을 만족하는 경로의 수를 구하세요. (단, 두 토끼는 구별됩니다)
알고리즘 분석
핵심 개념: Lindström-Gessel-Viennot Lemma
비교차 경로(non-intersecting paths) 문제는 행렬식을 이용한 LGV 보조정리로 해결합니다.
두 경로가 교차하지 않으려면:
- 토순이: (1,1) → (1,2) → … → (N-1,M) → (N,M)
- 토준이: (1,1) → (2,1) → … → (N,M-1) → (N,M)
또는
- 토순이: (1,1) → (2,1) → … → (N,M-1) → (N,M)
- 토준이: (1,1) → (1,2) → … → (N-1,M) → (N,M)
공식 유도
LGV lemma에 따르면:
| |
우리의 경우:
- C(n, k) = 조합(n, k)에서 n = N+M-4 (중간 이동 단계)
- det = C(N+M-4, N-2) × C(N+M-4, M-2) - C(N+M-4, N-1) × C(N+M-4, M-1)
두 토끼를 구별하므로 2를 곱합니다.
예제 분석
예제 1: N=2, M=2
| |
경로:
- 토순이 (1,2) → (2,2), 토준이 (2,1) → (2,2)
- 토순이 (2,1) → (2,2), 토준이 (1,2) → (2,2)
예제 2: N=3, M=4
| |
구현 전략
- 팩토리얼 전처리: O(N+M)
- 모듈로 역원 계산: Fermat’s little theorem 사용
- 조합 계산: C(n,r) = n! × (r!)^(-1) × ((n-r)!)^(-1) (mod 10^9+7)
- 행렬식 계산: 4개의 조합값으로 det 계산
코드 구현
| |
시간 복잡도 분석
| 요소 | 복잡도 |
|---|---|
| 팩토리얼 계산 | O(N+M) |
| 역팩토리얼 계산 | O(N+M) |
| 조합 계산 | O(1) × 4회 = O(1) |
| 전체 | O(N+M) |
공간 복잡도
- 팩토리얼 배열: O(N+M)
- 기타 변수: O(1)
- 전체: O(N+M)
주요 학습 포인트
- LGV 보조정리: 비교차 경로 개수를 행렬식으로 표현
- 모듈로 연산: 큰 수 처리 및 역원 계산
- 조합론: 격자 경로의 개수 계산
- Fermat의 소정리: 모듈로 역원 계산의 이론적 기초
실전 팁
- 모듈로 음수 처리:
(a - b + MOD) % MOD로 음수가 되는 것을 방지 - 오버플로우 방지: 모든 곱셈 후 모듈로 연산
- 팩토리얼 한계: 대수 N, M에 대해 미리 계산해두기
- 조합 재사용: 한 번 계산한 조합값을 변수에 저장
테스트 케이스
| N | M | 예상 답 | 설명 |
|---|---|---|---|
| 2 | 2 | 2 | 기본 예제 |
| 3 | 4 | 12 | 중간 크기 |
| 123456 | 78901 | 620455136 | 대수 (모듈로 적용) |
참고 자료:
- Lindström, B. (1985). “On the vector representation of induced matroids”
- Gessel, I., & Viennot, G. (1989). “Determinants, paths, and plane partitions”
- BOJ 27533 (SUAPC 2023 Winter L번)
![Featured image of post [Algorithm] C++ 백준 27533번 따로 걸어가기](/post/algorithm/2025-12-03-boj-27533-walk-separately-lindstrom-cpp-solution/wordcloud_hu_e325ea3670a2e4a9.png)
![[Algorithm] C++ 백준 17682번 Tents](/post/algorithm/2025-12-04-boj-17682-tents-combinatorics-cpp-solution/wordcloud_hu_2726d57ba0310c29.png)
![[Algorithm] C++ 백준 16481번 원 전문가 진우 - 방접원과 내접원의 관계](/post/algorithm/2025-12-03-boj-16481-excircle-incircle-geometry-cpp-solution/wordcloud_hu_ee675f3393f22f00.png)
![[Algorithm] C++ 백준 27533번 따로 걸어가기](/post/algorithm/2025-12-03-boj-27533-walk-separately-lindstrom-cpp-solution/wordcloud_hu_bcc1a69354c31bd3.png)
![[Algorithm] C++ 백준 6567번: 팔찌](/post/algorithm/2025-12-03-boj-6567-let-it-bead-polya-cpp-solution/wordcloud_hu_9f7bf9b3b4a09b24.png)
![[Algorithm] C++ 백준 11869번: 님블](/post/algorithm/2025-12-02-boj-11869-nimble-game-theory-cpp-solution/wordcloud_hu_bf915b4163fb4e18.png)
![[Algorithm] C++ 백준 13182번 제비](/post/algorithm/2025-12-04-boj-13182-lottery-draw-expectation-cpp-solution/wordcloud_hu_6c18b6c0307518c2.png)
![[Algorithm] C++ 백준 5051번: 피타고라스의 정리 (mod n)](/post/algorithm/2025-10-14-boj-5051-pythagorean-mod-n-cpp-solution/wordcloud_hu_7e8a5079e9226a49.png)
![[Algorithm] C++ 백준 16041번 : Double Clique](/post/algorithm/2025-08-12-boj-16041-double-clique-cpp-solution/wordcloud_hu_4d21b4066145dfb5.png)
![[Algorithm] C++/Python 백준 12735번: Boat](/post/algorithm/2025-08-14-boj-12735-boat-cpp-python-solution/wordcloud_hu_dfad17dd2b1a530d.png)