题目链接
洛谷P1057传球游戏
题目大意:
n
n
n个人围成圈传球,球只能左右传,求传的球经过
m
m
m次回到第一个人手中的所有情况
输入输出样例
输入
3 3
输出
2
思路:
动态规划,因为球传到第
i
i
i个人只有从
i
i
i的左边或者右边传,假设球经过
k
k
k次传到了第
i
i
i个人手中,那个最普通的情况应该有
f
[
i
]
[
k
]
=
f
[
i
−
1
]
[
k
−
1
]
+
f
[
i
+
1
]
[
k
−
1
]
f[i][k]=f[i-1][k-1]+f[i+1][k-1]
f[i][k]=f[i−1][k−1]+f[i+1][k−1]。考虑到
n
n
n个人成环,需对第
n
n
n和
1
1
1个人特殊考虑:
f
[
1
]
[
k
]
=
f
[
n
]
[
k
−
1
]
+
f
[
2
]
[
k
−
1
]
f[1][k]=f[n][k-1]+f[2][k-1]
f[1][k]=f[n][k−1]+f[2][k−1]
f
[
n
]
[
k
]
=
f
[
1
]
[
k
−
1
]
+
f
[
n
−
1
]
[
k
−
1
]
f[n][k]=f[1][k-1]+f[n-1][k-1]
f[n][k]=f[1][k−1]+f[n−1][k−1]
同时还需注意边界条件 f [ 1 ] [ 0 ] = 1 f[1][0]=1 f[1][0]=1,为了保证 f [ 2 ] [ 1 ] = 1 f[2][1]=1 f[2][1]=1成立
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
# define N 40
int f[N][40];
int main(int argc, char** argv) {
int n,m;
scanf("%d%d",&n,&m);
//f[i][k]=f[i-1][k-1]+f[i+1][k-1]
f[1][0]=1;//边界条件
for(int k=1;k<=m;k++){
//特殊情况
f[1][k]=f[2][k-1]+f[n][k-1];
for(int i=2;i<=n-1;i++)
f[i][k]=f[i-1][k-1]+f[i+1][k-1];
f[n][k]=f[1][k-1]+f[n-1][k-1];
}
printf("%d\n",f[1][m]);
return 0;
}