洛谷P1057 传球游戏

题目链接:https://www.luogu.org/problem/P1057

题目思路:
首先我们来看这道题,意思是说n个人,从1开始每个数都可以向左或向右移动一个单位,求移动m次后又回到1的方式

比如2个人 1 2 从1开始:移动2次回到1的方式只有1种。如果只移动1次,那永远回不到1。
那如果只移动0次的话,相当于没有移动。若当前位置就是1,那就是一种方法,即不移动,若当前位置不是1,说明移动一次无法到达1,所以是0种。

下面代码中, return 0 和 return 1的问题就是上面的理解。接下来用ans存储结果。因为一个数只能向左或向右走,并且由于围成一个圈,这里要考虑两种特殊情况:1的左边是n,n的右边是1,其余情况就是i-1和i+1(i为当前的位置)。所以移动m次到i的问题就可以分解成两个子问题,结果即移动m-1次到i的左边的个数 和 移动m-1次到i的右边的个数的和。

(PS:初始位置其实可以是1~n任意一个哒,这里图方便就选了1 =_=

参考代码:

#include<bits/stdc++.h>
using namespace std;
int n,m,dp[100][100];
int main()
{
	cin>>n>>m;//n个同学,传m次球
	for(int i=1;i<=100;i++)
		dp[0][i]=0;
	dp[0][1]=1;
	for(int i=1;i<=m;i++)//传球次数
		for(int j=1;j<=n;j++)
		{
			int left= (j==1 ? n:j-1);
			int right=(j==n ? 1:j+1);
				dp[i][j]=dp[i-1][left]+dp[i-1][right];
		//dp[i][j]表示经过i次传到编号为j的人手中的方案数,传到j号同学的球只能来自于j的左边一个同学和右边一个同学,
		//这两个同学的编号分别是left和right,所以可以得到以下的递推公式:dp[i][j]=dp[i-1][left]+dp[i-1][right];
		}
		cout<<dp[m][1];
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值