NOI2.6基本算法之动态规划 踩方格 分析----标志物的作用

一、题目描述

总时间限制: 1000ms 内存限制: 65536kB
描述

有一个方格矩阵,矩阵边界在无穷远处。我们做如下假设:
a.    每走一步时,只能从当前方格移动一格,走到某个相邻的方格上;
b.    走过的格子立即塌陷无法再走第二次;
c.    只能向北、东、西三个方向走;
请问:如果允许在方格矩阵上走n步,共有多少种不同的方案。2种走法只要有一步不一样,即被认为是不同的方案。

输入
允许在方格上行走的步数n(n <= 20)
输出
计算出的方案数量
样例输入
2

样例输出

7

二、分析


一道可以用递归来解决的题目。题目要求:“只能向北、东、西三个方向走”,所以可以写3个if,但是走东、西方向之后,可以走的路径是相同的,所以可以只写2个if。

int f(int n,int o)//n为能走的步数,o为标志物(1为向北走,0为向东、西走)。

{

if(o==1){//向北走

return f(n-1,0)+f(n-1,1)+f(n-1,0);//向北走之后可以走的方向的方案总数(继续向走或向东、西走)

}

if(o==0){//向东、西走

return f(n-1,0)+f(n-1,1);//向东、西走之后走的方向的方案总数(继续向东、西走或向北走)
}

}

现在这个函数还不完整,还要写边界。

int f(int n,int o)

{

if(n==0) return 0;//边界

if(o==1){

return f(n-1,0)+f(n-1,1)+f(n-1,0);

}

if(o==0){

return f(n-1,0)+f(n-1,1);
}

}

再写计算步数的代码。

int f(int n,int o)

{

if(n==0) return 0;

if(o==1){

if(n==1)

sum+=3;//计算步数

return f(n-1,0)+f(n-1,1)+f(n-1,0);

}

if(o==0){

if(n==1)

sum+=2;//计算步数

return f(n-1,0)+f(n-1,1);
}

}

这道题比较简单,做起来没有那么费力,也可以用算法解决,但是用算法比较麻烦,个人建议用递归的方法。


再来看一道题:

总时间限制: 10000ms 单个测试点时间限制: 1000ms 内存限制: 131072kB
描述

从一个无限大的矩阵的中心点出发,一步只能向右走、向上走或向左走。恰好走N步且不经过已走的点 
共有多少种走法? 

输入

一个数字,代表N,N<=1000

输出

输出有多少方案,最后结果模12345

样例输入
2
样例输出
7
一看数据范围就知道递归会爆,还要超时,看来不得不用动态规划了,状态转移方程也很容易找,

状态转移方程:f[n]=f[n-1]*2+f[n-2];

代码:

#include
int f[1005]={1,3};
int main()
{
	int i,n;
	scanf("%d",&n);
	for(i=2;i<=1005;i++){
		f[i]=(f[i-1]*2+f[i-2])%12345;
	}
	printf("%d",f[n]);
}



你可能感兴趣的:(NOI网站题目解析,动态规划,动态规划,函数,递归,状态转移)