題目連接: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 }
睡覺去了!