描述
n个同学站成一个圆圈,其中的一个同学手里拿着一个球,吹哨子时开始传球,每个同学可以把球传给自己左右的两个同学中的一个(左右任意),再次吹哨子时,传球停止,此时,拿着球没传出去的那个同学就是败者,要给大家表演一个节目。
问题:有多少种不同的传球方法可以使得从该同学手里开始传的球,传了m次以后,又回到该同学手里。两种传球的方法被视作不同的方法,当且仅当这两种方法中,接到球的同学按接球顺序组成的序列是不同的。比如有3个同学1号、2号、3号,并假设此同学为1号,球传了3次回到他手里的方式有1->2->3->1和1->3->2->1,共2种。
输入
输入有多组测试数据,一组数据输入占一行,为两个整数n,m(3<=n<=30,1<=m<=30).
输出
输出每组数据的传球种数,一组数据输出占一行,结果在int范围内。
样例输入
3 3
7 10
样例输出
2
252
分析:设i为传球次数,第j个人拿到球,易得只有传了i-1次且球在第j个人相邻两个人之一的人手里,第i次才能传到j的手中。
a[i][j] = a[i-1][j-1] + a[i-1][j+1] (1<j<n)
a[i][j] = a[i-1][n] + a[i-1][j+1] (j == 1)
a[i][j] = a[i-1][n-1] + a[i-1][1] (j == n)
1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 int main() 5 { 6 int n, m; 7 while (scanf("%d %d", &n, &m) != EOF) 8 { 9 int a[31][31] = {0}; 10 a[0][1] = 1; 11 for (int i = 1; i <= m; ++i) 12 for (int j = 1; j <= n; ++j) 13 { 14 if (j == 1) 15 a[i][j] = a[i-1][n] + a[i-1][j+1]; 16 else if (j == n) 17 a[i][j] = a[i-1][1] + a[i-1][n-1]; 18 else 19 a[i][j] = a[i-1][j-1] + a[i-1][j+1]; 20 } 21 printf("%d\n", a[m][1]); 22 } 23 system("pause"); 24 return 0; 25 }