10164번: 격자상의 경로
입력의 첫째 줄에는 격자의 행의 수와 열의 수를 나타내는 두 정수 N과 M(1 ≤ N, M ≤ 15), 그리고 ○로 표시된 칸의 번호를 나타내는 정수 K(K=0 또는 1 < K < N×M)가 차례로 주어지며, 각 값은 공백으
www.acmicpc.net
DP를 연습하던 중에 재미있는 풀이로 풀 수 있어서 가져와 봤다.
k가 존재하면 (0, 0)에서 k가 존재하는 인덱스 (i, j)까지 의 길 찾기 경우의 수 \(nCk\)로 구하고
그 k에서 (n - 1, m - 1)까지의 경우의수를 또 구하면 된다.
나이브하게 풀면 오버플로가 나고 dp테이블에 조합을 저장해 두고 풀어야 한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
#include <iostream>
using namespace std;
using ll = long long;
ll d[31][31], n, m, k;
int a, b, cnt;
ll comb(int n, int k) {
if (n == k || k == 0) return 1;
if (d[n][k]) return d[n][k];
return d[n][k] = comb(n - 1, k - 1) + comb(n - 1, k);
}
int main() {
cin >> n >> m >> k;
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
if (++cnt == k) {
a = i, b = j; break;
}
ll x, y;
if (k) x = comb(a + b, a);
else x = 1;
n = (n - 1) - a, m = (m - 1) - b;
y = comb(n + m, n);
cout << x * y << endl;
return 0;
}
|
cs |
고등학교 수학 지식을 활용해서 풀어보니 재밌었다.
'알고리즘 > BOJ' 카테고리의 다른 글
BOJ 5014 스타트링크 (0) | 2020.12.10 |
---|---|
BOJ 11066 파일 합치기 (0) | 2020.12.05 |
BOJ 6087 레이저 통신 (0) | 2020.12.02 |
BOJ 14442 벽 부수고 이동하기 2 (0) | 2020.12.02 |
BOJ 3197 백조의 호수 (0) | 2020.12.01 |