N개의 결점은 얼마나 다른 두 갈래 나무를 구성할 수 있는가
시간 제한 1000ms, 메모리 제한 256000kB, 코드 길이 제한 8000B
줄마다 자연수 n을 입력하여 두 줄, 줄마다 숫자를 출력합니다. 각각: 노드가 n인 두 갈래 트리에는 ___심다각 노드에 빨간색, 검은색 두 가지 색상이 있을 수 있는 경우 ___심다
입력 예:
일
이
출력 예:
일
이
이
팔
사고방식: 이 문제는 바로 Catalan수의 응용 중 하나이다. N개의 결점은 얼마나 다른 두 갈래 나무를 구성할 수 있는지.
문제1에 대해 N개의 결점을 설정하면 f(N)개의 서로 다른 두 갈래 나무를 구성할 수 있다. 만약에 왼쪽 나무에 M개의 결점이 있다면 오른쪽 나무에 N-M-1개의 결점이 있다. 이때 하위 나무 개수는 각각 (M, N-M-1)인 두 갈래 나무는 f(M)*f(N-M-1)종이고 M은 0에서 N-1로 가져올 수 있기 때문에 f(N)=f(0)*f(N-1)+f(N-2)+·+f(M)*f(N-1)*f(0),f(0),f() = 1, f (1) = 1.상식은 바로 Catalan 수의 계산 공식이다.
Catalan 수의 계산 공식은 다음과 같습니다.
f(n)=f(n-1)*(4*n-2)/(n+1);
f(n)=C(2n,n)/(n+1) (n=0,1,2,...);
f(n)=C(2n,n)-C(2n,n+1)(n=0,1,2,...);
C (2n, n) 는 조합수이며, 여기서 빨간색으로 표시된 공식을 선택하여 계산합니다.
문제2, 각 결점은 빨간색과 검은색일 수 있기 때문에 N개의 결점은 2^N에서 가능한 색깔로 배열되고 위에 있는 두 갈래 나무의 종류수, 즉 착색된 두 갈래 나무의 종류수: 2^N*f(N)
#include <iostream>
#include <math.h>
#include <queue>
typedef unsigned long long ULONG;
ULONG Factorial(ULONG N) {
if (N < 0) return 0;
ULONG result = 1;
for (ULONG i = 2; i <= N; ++ i)
result *= i;
return result;
}
ULONG Catalan(ULONG N) {
if (N < 0) return 0;
if (N == 0) return 1;
if (N == 1) return 1;
ULONG fn = Factorial(N);
ULONG comb = Factorial(2*N) / (fn * fn);
return comb / (N + 1);
}
void CatalanReadData() {
std::queue<int> input;
int N;
while (std::cin >> N) {
input.push(N);
}
while (!input.empty()) {
ULONG cata = Catalan(input.front());
std::cout << cata << std::endl;
std::cout << (ULONG)pow((double)2, input.front()) * cata <<std::endl;
input.pop();
}
}
PS: 유도, 기계시험, 2013, 학교 모집
참조:
[1] http://blog.csdn.net/ffjjqqjj/article/details/6081711
[2] http://baike.baidu.com/view/2499752.htm
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.