上面的题解讲的很详细了,我补充几句,dp[i][j]表示第j次选第i人的方法数,根据题意,每一个人可以从他左边的人与右边的人拿到球,因此要将第一个人左边与右边的人初始化为1,不过由次要注意第一个人不可能自己传给自己,因此要特判,详情见代码;
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=35;
int n,m;
int dp[N][N];
inline int read()
{
int x=0,t=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')t=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return x*t;
}
int main()
{
n=read(),m=read();
//回忆dp数组的含义,传0次代表从起点开始
//传一次只能由起点往左右传,因此只用初始化起点左右两边的人即可
dp[1][1]=dp[n-1][1]=1;
for(int j=2;j<=m;j++)//先按传的次数遍历,上边传一次已经初始化过了,2开始
for(int i=0;i<n;i++)
{
//特判条件,自己不能传给自己
if((i-1+n)%n==0&&j==2)dp[i][j]=dp[(i+1+n)%n][j-1];
else if((i+1+n)%n==0&&j==2)dp[i][j]=dp[(i-1+n)%n][j-1];
else dp[i][j]=dp[(i-1+n)%n][j-1]+dp[(i+1+n)%n][j-1];
}
cout<<dp[0][m]<<endl;
}