题目连接:http://ybt.ssoier.cn:8088/problem_show.php?pid=1196
备递归算法的时候遇到这道题,没有发现递推式,看完网路题解才能推出来
题解如右连接,看完恍然大悟 https://www.cnblogs.com/sjymj/p/5379221.html当然这种方法有点动态规划的意思
题解
l[i]表示最后一步向左走到达第i个格,那么它上一格不能是从右边走得到,r[i]表示最后一步向右走到达第i个格,那么它上一格不能是从左边走得到,u[i]表示最后一步先上走到达第i个格;
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 int n,ans; 5 int l[30],r[30],u[30]; 6 int main() 7 { 8 cin>>n; 9 if (n==1) cout<<3; 10 else 11 { 12 l[1]=1; 13 r[1]=1; 14 u[1]=1; 15 for (int i=2;i<=n;i++) 16 { 17 l[i]=l[i-1]+u[i-1]; 18 r[i]=r[i-1]+u[i-1]; 19 u[i]=l[i-1]+r[i-1]+u[i-1]; 20 } 21 ans=l[n]+r[n]+u[n]; 22 cout<<ans<<endl; 23 } 24 return 0; 25 }
又找到另外一种题解方式,显然有递推思想也有动态规划的意思 https://blog.csdn.net/g_meteor/article/details/70169748
这道题为一道递推问题,可向上走、左走跟右走,但是需要注意的是往右走的那条路就不能往左走了。即有递推公式a[i]=a[i-1]+(2*a[i-2]+a[i-1]-a[i-2])=2*a[i-1]+a[i-2],a[i-1]表示往上走的那一路种类数,2*a[i-2]+a[i-1]-a[i-2]表示往左右两个方向的种类数。
源代码如下:
1 #include<bits/stdc++.h> 2 using namespace std; 3 int main() 4 { int n,i,a[21]; 5 cin>>n; 6 a[0]=1; 7 a[1]=3; 8 for(i=2;i<21;++i) 9 a[i]=2*a[i-1]+a[i-2]; 10 cout<<a[n]<<endl; 11 }
但两种方法对于蒟蒻来说其实在初期很难想到,毕竟题出自POJ,可想难度
但是面对这样一道典型dfs,我还是可以写出的,悲剧的是居然用了2个小时
主要是调试以下代码就用了1个小时,仅以此代码铭记我的错误
1 #include<iostream> 2 using namespace std; 3 int next[3][2]={{-1,0},{0,1},{1,0}}; 4 int n, cnt=0; 5 int v[500][500]; 6 void dfs(int x, int y, int step) 7 { 8 if(step>=n){ 9 cnt++; 10 return; 11 } 12 for(int i=0; i<3; i++) 13 { 14 int tx=x+next[i][0]; 15 int ty=y+next[i][1]; 16 if(!v[tx][ty]) 17 { 18 v[tx][ty]=1; 19 dfs(tx, ty, step+1); 20 v[tx][ty]=0; 21 } 22 } 23 } 24 int main() 25 { 26 cin>>n; 27 dfs(0, 0, 0); 28 cout<<cnt; 29 return 0; 30 }
调试之后的代码,愉快AC!
1 #include<iostream> 2 using namespace std; 3 int next[3][2]={{-1,0},{0,1},{1,0}}; 4 int n, cnt=0; 5 int v[1000][1000];//是否被访问过 6 void dfs(int x, int y, int step) 7 { 8 v[x][y]=1;//当前调用即代表改点访问过了 9 if(step>=n){ 10 cnt++; 11 return; 12 } 13 for(int i=0; i<3; i++) 14 { 15 int tx=x+next[i][0]; 16 int ty=y+next[i][1]; 17 if(!v[tx][ty]) 18 { 19 v[tx][ty]=1; 20 dfs(tx, ty, step+1); 21 v[tx][ty]=0; 22 } 23 } 24 } 25 int main() 26 { 27 cin>>n; 28 dfs(500, 500, 0);//注意此处500,500坐标是在第一象限定义了一个起点,因为n≤20所以这样定义就不会数组出现负数了 29 cout<<cnt; 30 return 0; 31 }
睡觉去了!
原文地址:https://www.cnblogs.com/tflsnoi/p/9601912.html
时间: 2024-10-10 09:42:12