문제 링크입니다: https://www.acmicpc.net/problem/1010
이 문제의 핵심은 서쪽의 첫번째 사이트가 연결한 다리를 고정으로 놓고 부분문제로 나누는 것이였습니다.
테스트 케이스를 입력 받고 그만큼 반복해서 답을 도출해야하기 때문에 미리 모든 경우의 수를 계산해놓고 결과를 출력하는 형식으로 코드를 작성했습니다.
/*
강 주변에서 다리를 짓기에 적합한 곳을 사이트라고 한다.
재원이는 강 주변을 면밀히 조사해 본 결과 강의 서쪽에는 N개의 사이트가 있고 동쪽에는 M개의 사이트가 있다는 것을 알았다. (N ≤ M)
재원이는 서쪽의 사이트와 동쪽의 사이트를 다리로 연결하려고 한다. (이때 한 사이트에는 최대 한 개의 다리만 연결될 수 있다.)
재원이는 다리를 최대한 많이 지으려고 하기 때문에 서쪽의 사이트 개수만큼 (N개) 다리를 지으려고 한다.
다리끼리는 서로 겹쳐질 수 없다고 할 때 다리를 지을 수 있는 경우의 수를 구하는 프로그램을 작성하라.
*/
#include <iostream>
#include <cstring> //memset
using namespace std;
int cache[31][31]; //West<=30, East<=30
int West, East; //서쪽 동쪽 다리 수
//West의 제일 위 사이트가 이은 다리를 고정하고 부분문제로 나눈다
//예를 들어 West가 2, East가 5
//West의 첫번째 사이트가 East의 맨 위 사이트와 연결할 경우-> 남은 West 사이트(1)와 남은 East 사이트(4)=cache[1][4]
//West의 첫번째 사이트가 East의 두번째 사이트와 연결할 경우->남은 West 사이트(1)와 남은 East 사이트(3)=cache[1][3]
//West의 첫번째 사이트가 East의 세번째 사이트와 연결할 경우->남은 West 사이트(1)와 남은 East 사이트(2)=cache[1][2]
//West의 첫번쨰 사이트가 East의 세번째 사이트와 연결할 경우->남은 West 사이트(1)와 남은 East 사이트(1)=cache[1][1]
//예를 들어 West가 3, East가 5
//West의 첫번째 사이트가 East의 맨 위 사이트와 연결할 경우-> 남은 West 사이트(2)와 남은 East 사이트(4)=cache[2][4]
//West의 첫번째 사이트가 East의 두번째 사이트와 연결할 경우->남은 West 사이트(2)와 남은 East 사이트(3)=cache[2][3]
//West의 첫번째 사이트가 East의 세번째 사이트와 연결할 경우->남은 West 사이트(2)와 남은 East 사이트(2)=cache[2][2]
void preCalculate(void) //미리 계산
{
memset(cache, 0, sizeof(cache));
for (int i = 1; i < 31; i++)
cache[1][i] = i; //West에 하나일 때는 East만큼의 방법뿐
//설명은 위 주석
for (int i = 2; i <= 30; i++)
for (int j = i; j <= 30; j++)
for (int k = j; k >= i; k--)
cache[i][j] += cache[i - 1][k - 1];
}
int main(void)
{
int test_case;
cin >> test_case;
preCalculate();
for (int i = 0; i < test_case; i++)
{
cin >> West >> East;
cout << cache[West][East] << endl;
}
return 0;
}
개발환경:Visual Studio 2017
지적, 조언, 질문 환영입니다! 댓글 남겨주세요~
'알고리즘 > BOJ' 카테고리의 다른 글
백준 1931번 회의실배정 (0) | 2018.02.13 |
---|---|
백준 11052번 붕어빵 판매하기 (0) | 2018.02.13 |
백준 2193번 이친수 (0) | 2018.02.12 |
백준 9095번 1, 2, 3 더하기 (0) | 2018.02.11 |
백준 9252번 LCS2 (0) | 2018.02.11 |