题目说明
用绳子连接纸杯制作“纸杯电话”——这应该勾起了很多人对理科实验的回忆。
如果把绳子拉直,对着一边的纸杯讲话,声音就可以从另一边的纸杯传出。
假设有几个小朋友以相同间隔围成圆周,要结对用纸杯电话相互通话。
如果绳子交叉,很有可能会缠绕起来,所以结对的原则是不能让绳子交叉。
举个例子,如果有 6 个小朋友,则只要如下图一样结对,
就可以顺利用纸杯电话通话。也就是说,6 个人的时候,有 5 种结对方式。
求:有 16 个小朋友的时候,一共有多少种结对方式?
思路
1.将16个小朋友分成两组,每组都是偶数个小朋友(分割线也占两个小朋友)
2.比如第一组有x种结对方式,第二组有y种结对方式,则一共有x*y种结对方式
比如有4对小朋友(8人),则结对方式如下图所示
假设用pair[4]表示4对小朋友时一共有多少种结对方式,则根据上图可以得出如下结论:
pair[4] = pair[0]*pair[3] + pair[1]*pair[2] + pair[2]*pair[1] + pair[3]*pair[0]
代码
public static void main(String[] args) {
int n = 16; // 小朋友的人数
int [] pair = new int[n / 2 + 1]; // 下标表示小朋友有几对,元素的值表示结对方式有几种。
// 比如pair[3]=5表示3对小朋友的结对方式有5种
pair[0] = 1; // 因为要相乘,所以设为1
// 计算i对小朋友的结对方式有几种
for(int i = 1; i <= n/2; i ++){
// 结合思路中的图,可得如下规律
for(int j = 0; j < i; j ++){
pair[i] += pair[j] * pair[i - j - 1];
}
}
System.out.println(pair[n/2]); // pair数组:[1, 1, 2, 5, 14, 42, 132, 429, 1430]
}
结果
1430