티스토리 뷰
728x90
문제 링크
https://www.acmicpc.net/problem/1010
다음과 같은 그림에서 서쪽 사이트의 개수만큼 다리를 지으려 할 때 겹치지 않게 다리를 모두 지을 수 있는 경우의 수를 구해야 한다.
다리끼리는 서로 겹쳐질 수 없다라는 조건이 있다.
이런 경우는 가능하지만
이런 경우는 불가능하다는 것이다.
서쪽 사이트의 집합을 A, 동쪽 사이트의 집합을 B라 하면
1≤i,j≤N 인 i,j와
1≤x,y≤M 인 x,y에 대해
A[i]와 B[x],A[j]와 B[y]가 연결된다면 항상 i<j이고 x<y여야 한다.
쉽게 말하면 서쪽의 두 정점과 동쪽의 두 정점이 연결된다면 항상 순서대로 연결되어야 한다는 말이다.
확장해서, 서쪽과 동쪽에서 각각 정확히 N개의 정점을 선택할 때 양쪽의 정점은 항상 순서대로 연결되게 된다.
서쪽의 정점 N개는 모두 선택되어야 하고, 동쪽의 사이트 M개 중에서 어떤 N개의 정점을 선택했을 때 다리를 지을 수 있는 방법의 수는 항상 1이다.
따라서 우리는 이 문제를 M개 중 N개를 고르는 경우의 수를 구하는 문제로 단순화할 수 있다.
이는 결국 조합 mCn 이 몇인가를 묻는 문제이다.
정답 코드
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <cstring> | |
using namespace std; | |
int t; | |
int d[31][31]; | |
int foo(int n, int r) { | |
if (n == r || r == 0) | |
return 1; | |
if (d[n][r]) return d[n][r]; | |
return d[n][r] = foo(n - 1, r - 1) + foo(n - 1, r); | |
} | |
int main() { | |
cin >> t; | |
while (t--) { | |
memset(d, 0, sizeof(d)); | |
int n, m; | |
cin >> n >> m; | |
cout << foo(m, n) << '\n'; | |
} | |
} |
728x90
'알고리즘 > 문제 풀이' 카테고리의 다른 글
[BOJ] 백준 15917 노솔브 방지문제야!! (2) | 2018.07.25 |
---|---|
[BOJ] 백준 15916 가희는 그래플러야!! (0) | 2018.07.25 |
[2018 IUPC] 백준 15784 질투진서 (4) | 2018.07.05 |
[BOJ] 백준 12888 완벽 이진 트리 도로 네트워크 (0) | 2018.07.05 |
[2018 IUPC] 백준 15782 Calculate! 2 (4) | 2018.06.29 |
댓글