问题:一个凸 n 边形中,通过不相交的对角线将 n 边形分割成若干三角形,不同的拆分数目用 h[n] 表示, 五边形有5种拆分法,因此h[5] = 5;
分析:凸 n 边形的任意一条边都必然是一个三角形的一条边,因为不在同一直线上的三点确定一个三角形,可以在p[2]、p[3]、……、p[n-1]中找出一点与p[1]、p[n]构成一个三角形,就将凸 n 边形分割成三个区域,如下图所示。其中区域2是一个三角形,区域1是一个凸 k边形,拆分方案数是h[k],区域3是一个凸 n-k+1边形,拆分方案数是h[n-k+1],此时的拆分方案总数为h[k]h[n-k+1],由于p[k]可以是p[2]、p[3]、……、p[n-1]中的任一点,由加法原理,凸 n 边形拆分总的方案数为Σh[i]h[n-i+1],其中 1< i <n,边界条件为h[2] = 1。
#include <iostream>
using namespace std;
int main()
{
int n, ans = 1;
int h[10] = { 0,0,1 };
cin >> n;
for (int i = 3; i <= n; ++i)
{
for (int j = 2; j < i; ++j)
{
h[i] = h[i] + h[j] * h[i - j + 1];
}
}
cout << h[n] << endl;
return 0;
}
递推公式可以简化为h[n] = C[n-1, 2n-2] / n。
相似的问题
- 树的计数问题:有 n 个节点的二叉树共有多少棵?
- 用括号括 n 个数的乘积:有n个数的连乘积k[1]k[2]k[3]……k[n],插入足够的括号使每一个子乘积恰好是两个因子的乘积,不允许改变k[i]的次序。