NOIP 2008 传球游戏

Posted 绝爵觉

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NOIP 2008 传球游戏相关的知识,希望对你有一定的参考价值。

 这道题呢,我用了一下搜索,还用了一下dp

搜索是40PAC,dp是稳过的

然后呢遇到边缘值我都进行了特殊判断,我感觉这么写好写点

先来看看搜索

#include<bits/stdc++.h>
using namespace std;

int n;
int m;
struct node
{
	int now;//现在的位置
	int cnt;//次数
};
queue<node> q;//用队列解决bfs

void bfs(int x,int sum)
{
	if(sum==m)
	{
		q.push((node){x,sum});//符合题解,入队
		return;
	}
	if(x==1)//特判1
	{
		q.push((node){n,sum+1});
		q.push((node){2,sum+1});
	}
	else if(x==n)//特判n
	{
		q.push((node){1,sum+1});
		q.push((node){n-1,sum+1});
	}
	else 
	{
		q.push((node){x+1,sum+1});
		q.push((node){x-1,sum+1});
	}
	return;
}

int main()
{
	cin>>n>>m;
	q.push((node){1,0});
	while(q.front().cnt!=m)//不符合就一直搜索下去
	{
		bfs(q.front().now,q.front().cnt);
		q.pop();//不符合的都出队
	}
	int ans=0;
	while(!q.empty())
	{
		if(q.front().now==1) ans++;
		q.pop();
	}
	cout<<ans;
	return 0;
}

f[i][j]表示 传了i次球,到第j个人了

接下来是dp算法了,还是得特判1和n,主体公式如下

 最后呈上ac代码

#include<bits/stdc++.h>
using namespace std;

int n;
int m;
int f[31][31];

int main()
{
	cin>>n>>m;
	memset(f,0,sizeof(f));
	f[0][1]=1;//边界值
	for(int i=1;i<=m;i++)
	{
		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];
	return 0;
}

以上是关于NOIP 2008 传球游戏的主要内容,如果未能解决你的问题,请参考以下文章

noip2008普及组t3传球游戏

NOIP 2008 传球游戏

Codevs 1148 == 洛谷 P1057 传球游戏

2008传球游戏

传球游戏

P1057 传球游戏