DP数组表示和含义 :

dp[ n ][ m ] = t 就表示有 t 种方案可以实现 :经过 m 次传球,最终落在 n 号的手里。

思考 :

1. 要想知道 dp[ n ][ m ] 等于多少,需要知道有多少种方案可以实现 经过 m - 1 次传球最终落在 n 号左边的人手里,和有多少种方案可以实现 经过 m - 1 次传球最终落在 n 号右边的人手里。
2. 同学们围一个圈,那么第 n 号人的左边是 1 号同学,同理 1 号同学的右边是 n 号同学。
数组表示 : a[ 1 ] ~ a[ n ] 分别表示 1 号同学到 n 号同学,让a[ 0 ] = n 再让 a[ n + 1 ] = 1。这样可以通过a[ i - 1 ]和a[ i + 1 ]来表示 i 号同学左右两边的人的号码。

状态转移方程

dp[ n ][ m ] = dp[ n - 1 ][ m - 1] + dp[ n + 1 ][ m - 1 ]
#include<bits/stdc++.h>
using namespace std;

int dp[50][50];

int main()
{
    int n,m,a[50];      //a数组用来表示同学们围的圈
    cin >> n >> m;
    
    a[0] = n; a[n + 1] = 1;    // 让同学们首尾相连
    for (int i = 1; i <= n; i ++ )
        a[i] = i;
    
    dp[2][1] = 1; dp[n][1] = 1;   // 从1号同学出发,经过1次传球只能到2号和 n 号手里
    for (int i = 2; i <= m; i ++ ) // i 表示经过 i 次传球,经过1次传球的可能性在上面列完了,所以从2开始
        for (int j = 1; j <= n; j ++ ) 
            dp[a[j]][i] = dp[a[j - 1]][i - 1] + dp[a[j + 1]][i - 1];
    
    cout << dp[1][m] << endl;
    return 0;
}