传球游戏
它似乎很经典,标签递归,所以我写了一个特别纯的递归
代码1
#include <bits/stdc++.h>
using namespace std;
int n,m,ans=0;
void dfs(int k,int s)//现在球在k的手里,已经传了s次
{
if (s==m)
{
if (k==1) ans++;
return;
}//得到一组解
else if (k==1)
{
dfs(n,s+1);
dfs(2,s+1);
}//球在第一个人的情况
else if (k==n)
{
dfs(1,s+1);
dfs(n-1,s+1);
}//球在最后一个人手中的情况
else
{
dfs(k-1,s+1);
dfs(k+1,s+1);
}//其他情况
return;
}
int main()
{
cin>>n>>m;
dfs(1,0);
cout<<ans;
}
不幸的是,它超时了,虽我加上一点剪枝,但还是没有过。于是我们迎来了第二个版本。与之前完全不同的思路,这道题是求方案数,加法原理,所以。
代码2
#include <bits/stdc++.h>
using namespace std;
int n,m;
int yia(int now,int k)//球在now号手上,传k次的方案数
{
if (now==1&&k==0) return 1;//这种情况下1种情况
else if (k==0) return 0;//一次都没传时是在1号手上的,所以就这样了
if (now==1) return yia(n,k-1)+yia(2,k-1);
if (now==n) return yia(1,k-1)+yia(n-1,k-1);
return yia(now-1,k-1)+yia(now+1,k-1);//自行理解吧
}
int main()
{
cin>>n>>m;
cout<<yia(1,m);
return 0;
}
这样的程序依旧是超时的,但是它提供了一种思路,于是就有了递推~~
代码3
#include <bits/stdc++.h>
using namespace std;
int n,m,a[100][100]={};
int main()
{
cin>>n>>m;
a[1][0]=1;//状态与代码2描述的是一样的
for (int k=1;k<=m;k++)
for (int i=1;i<=n;i++)
{
if (i==1) a[i][k]=a[n][k-1]+a[2][k-1];
if (i==n) a[i][k]=a[1][k-1]+a[n-1][k-1];
if (i>1&&i<n) a[i][k]=a[i-1][k-1]+a[i+1][k-1];
}
cout<<a[1][m];
return 0;
}
满分~~
完结撒花!