传球游戏(递推)

描述 

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 }    

 

原文地址:https://www.cnblogs.com/PegasusWang/p/2870426.html