sicily 传球游戏

 1 #include <iostream>
 2 #include <memory.h>
 3 using namespace std;
 4 int main() {
 5     int m, n;
 6     cin >> n >> m;
 7     int a[m+1][n+1];
 8     memset(a, 0, sizeof(a));
 9     a[1][2] = 1;
10     a[1][n] = 1;
11     for (int i = 2; i <= m; i++) {
12         for (int j = 1; j <= n; j++) {
13             if (j == 1) {
14                 a[i][j] = a[i-1][2] + a[i-1][n];
15             } else if (j==n) {
16                 a[i][j] = a[i-1][j-1] + a[i-1][1];
17             } else {
18                 a[i][j] = a[i-1][j+1] + a[i-1][j-1];            
19             }
20         }
21     }
22     cout << a[m][1] << endl;
23     return 0;
24 }
游戏规则是这样的:n个人站成一个圆圈,其中的一个人手里拿着一个球,当裁判吹哨子时开始传球,每个人可以把球传给自己左右的两个人中的一个(左右任意),当裁判再次吹哨子时,传球停止,此时,拿着球没传出去的那个人就是败者,要给大家表演一个节目。一般是表演唱歌跳舞balabala。因此智锐最希望自己失败了 !
 
    聪明的智锐提出一个有趣的问题:有多少种不同的传球方法可以使得从他手里开始传的球,传了m次以后,又回到他手里。两种传球的方法被视作不同的方法,当且仅当这两种方法中,接到球的人按接球顺序组成的序列是不同的。比如有3个人,1号、2号、3号,并假设智锐为1号,球传了3次回到智锐手里的方式有1->2->3->1和1->3->2->1,共2种。 
 
Input

 输入共一行,有两个用空格隔开的整数n,m(3<=n<=30,1<=m<=30)。 

Output

 输出共一行,有一个整数,表示符合题意的方法数。 

Sample Input
 Copy sample input to clipboard
3 3 
Sample Output
2



解题:
动态规划,找出方程 dp[i][j] = dp[i-1][j-1] + dp[i-1][j+1]
i表示传球次数,j表示第几个人 dp[i][j]表示传了i次后回到j手里,有多少种方法/路径
可以想当处在dp[i-1][j-1]的时候,传多一次时,j-1他可以可以把求穿个隔壁j或j-2,则j多了dp[i-1][j-1]种,由于每个人都有与其相邻的另外两个人,所以为dp[i-1][j-1] + dp[i-1][j+1]
需要先对只传一次的情况赋值,以此去推出当次数增加时,其他人的情况


posted @ 2014-03-16 16:49  向日葵的祈愿  阅读(227)  评论(0)    收藏  举报