算法题(201):传球游戏
审题:
本题需要我们找到经过m次传球后球回到编号为1的同学手里的所有方案数
思路:
方法一:动态规划本题是多阶段重复子问题,我们尝试使用动态规划解决
(1)状态表示:f[i][j]表示经过i次传球后到达第j号同学手上的所有方案数
(2)状态转移方程:
由于传球只能左右传递,且同学们围成圆形,所以分为两大类。第一类:中间的同学
第二类:两端的同学
由于求的是f[i][j],也就是传了第i次到达j位置的,所以是从传了i-1次的左右相邻同学传递而来
(3)初始化:
根据状态转移方程:我们的f[0][1]不能初始化为0,否则所有的值都会为0
然后根据经验,我们可以尝试初始化为1,然后对填表进行一两行的模拟,判断是否会出问题
经过模拟尝试,发现确实要初始化为1
(4)填表顺序:从上到下
(5)输出答案:直接输出f[m][1],因为题目要的就是经过m次传球后给到第一位同学的总方案数
解题:
#include<iostream> using namespace std; int n, m; int f[35][35];//f[i][j]表示传递了i次后到达j的方案数 int main() {cin >> n >> m;//初始化f[0][1] = 1;for (int i = 1; i <= m; i++)//行表示次数m{for (int j = 1; j <= n; j++)//列表示人数{//两侧的人if (j == 1){f[i][j] = f[i - 1][2] + f[i - 1][n];}else if (j == n){f[i][j] = f[i - 1][1] + f[i - 1][n - 1];}else//中间的人{f[i][j] = f[i - 1][j - 1] + f[i - 1][j + 1];}}}//输出答案cout << f[m][1] << endl;return 0; }
P1057 [NOIP 2008 普及组] 传球游戏 - 洛谷