一、问题描述
二、问题分析
首先需要明确的是每个结点都是不同的所以在分组计算时就无需考虑旋转重复,如图中第一行第二个和第二行第一个被视为不同的结对方式。然后就是对问题的拆分,能够发现对于一个大问题来说,可以将其拆分为若干两个小问题,而这个大问题的解可以由这子问题的解组合出来。即将n个结点分为3组,其中1组为分割组只有两个结点,剩下的结点分为两组,也就是两个子问题组。在实现过程中可以通过使用数组存储避免重复计算,代码如下。
三、代码实现
1.C/C++实现
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
// counts[i] 存放 i 个人的结对方式
// 当 i 为奇数时,counts[i] = 0
int counts[20];
memset(counts, 0, sizeof(counts));
counts[0] = counts[2] = 1;
// 递推
for (int i = 4; i < 20; i += 2)
for (int j = 0; j <= i - 2; j += 2)
counts[i] += counts[j] * counts[i - j - 2];
cout << counts[16] << endl;
return 0;
}
2.Python实现
# coding=utf-8
ways = [1, 1]
def get_ways(num):
if num % 2:
return 0
else:
index = num // 2
next_index = len(ways)
# 如果 list 中元素不够则进行扩充
while next_index <= index:
tmp = 0
for i in range(0, next_index):
tmp += ways[i] * ways[next_index - i - 1]
ways.append(tmp)
next_index += 1
return ways[index]
if __name__ == '__main__':
print(get_ways(16))