OpenJ_Bailian 4103 踩方格(搜索 动态规划 )
描述
有一个方格矩阵,矩阵边界在无穷远处。我们做如下假设:
a. 每走一步时,只能从当前方格移动一格,走到某个相邻的方格上;
b. 走过的格子立即塌陷无法再走第二次;
c. 只能向北、东、西三个方向走;
请问:如果允许在方格矩阵上走n步,共有多少种不同的方案。2种走法只要有一步不一样,即被认为是不同的方案。
输入
允许在方格上行走的步数n(n <= 20)
输出
计算出的方案数量
样例输入
2
样例输出
7
解题思路:
1.递归:从 (i,j) 出发,走n步的方案数,等于以下三项之和:
从(i+1,j)出发,走n-1步的方案数。前提:(i+1,j)还没走过
从(i,j+1)出发,走n-1步的方案数。前提:(i,j+1)还没走过
从(i,j-1)出发,走n-1步的方案数。前提:(i,j-1)还没走过
逐层往下搜。
或者用状态转移:
要是最后一步是向左走,则前一步不能为向右走 l[i]=l[i-1]+u[i-1]
要是最后一步是向右走,则前一步不能为向左走 r[i]=r[i-1]+u[i-1]
要是最后一步是向上走,则前一步是什么无影响 u[i]=l[i-1]+r[i-1]+u[i-1]
可得公式:f[i]=l[i]+r[i]+u[i]
=2*l[i-1]+2*r[i-1]+3*u[i-1]
=2*f[i-1]+u[i-1]
=2*f[i-1]+f[i-2]
#include<cstdio> int vis[30][30]= {0}; int ways(int x,int y,int n) { if (n==0) return 1; vis[x][y]=1; int num=0; if (!vis[x][y-1]) num+=ways(x,y-1,n-1); if (!vis[x][y+1]) num+=ways(x,y+1,n-1); if (!vis[x+1][y]) num+=ways(x+1,y,n-1); vis[x][y]=0; return num; } int main() { int n; scanf("%d",&n); printf("%d\n",ways(0,22,n)); return 0; }
#include<cstdio> int l[25],r[25],u[25]; int main() { int n; scanf("%d",&n); l[1]=r[1]=u[1]=1; for (int i=2; i<=n; i++) { l[i]=l[i-1]+u[i-1]; r[i]=r[i-1]+u[i-1]; u[i]=l[i-1]+r[i-1]+u[i-1]; } printf("%d\n",l[n]+u[n]+r[n]); return 0; }
#include<stdio.h> int f[22]; int main() { int n; scanf("%d",&n); f[1]=3,f[2]=7; for (int i=3; i<=n; i++) f[i]=2*f[i-1]+f[i-2]; printf("%d\n",f[n]); return 0; }