【動態規劃】洛谷-過河卒
阿新 • • 發佈:2018-12-13
ges ret block 深度搜索 說明 cin 過河 簡單 中馬
一、題目
二、做題總結
- 本題之前在ZSC上是做過的,當初用的是DFS深度搜索,這次在洛谷上還是原來的思路,卻被提示TLE!!原來在ZSC上這道題的測試數據是被簡化過的,當在洛谷遇到坐標比較高的時候就超時了
因為沒有接觸過DP 雖然知道要用遞推代替遞歸 但最後還是沒想明白怎麽寫 查詢資料之後知道了這道題可以用動態規劃DP來做 很簡單的狀態轉移方程式:
dp[i][j]=dp[i-1][j]+dp[i][j-1]
(第 dp[i][j] 個位置到達的可能性是第 dp[i-1][j] 個位置方案數 + 第 dp[i][j-1] 個位置的方案數)
三、之前解題的總結和DFS代碼【會TLE】
- 題目中馬以“日”字形沿各方向跳出的點才是題目中所謂馬控制的九個點,而不是馬坐標周圍的九個點
- 題目的坐標系是以第四象限為平面,卒可向下或向右
- dfs求路徑總數要設置邊界(1)到達目的地結束 (2)碰到障礙物結束 (3)越界結束
#include <iostream> using namespace std; int m,n; long long arr[25][25]={0}; void dfs(int x,int y,long &router) { if(arr[x][y]==9) { router++; return; } if(arr[x][y]==-1) return; if(x>m || y>n) return; dfs(x+1,y,router); dfs(x,y+1,router); } int main() { int a,b; cin>>m>>n>>a>>b; long long router=0; //對馬食的九個位置置-1 arr[a][b]=-1; arr[a+1][b+2]=-1; if(a-1>=0) arr[a-1][b+2]=-1; arr[a+2][b+1]=-1; if(a-2>=0) arr[a-2][b+1]=-1; if(b-1>=0) arr[a+2][b-1]=-1; if(a-2>=0 && b-1>=0) arr[a-2][b-1]=-1; if(b-2>=0) arr[a+1][b-2]=-1; if(a-1>=0 && b-2>=0)arr[a-1][b-2]=-1; dfs(0,0,router); cout<<router<<endl; }
四、使用DP解題【AC】
- 註意:題目明確說明數據很大 所以數組聲明時要用long long
#include <iostream> using namespace std; int m,n; long long arr[25][25]={0}; void dp() { if(arr[0][0]==-1) return; //馬食位置 arr[0][0]=1; for(int i=0;i<=m;i++) for(int j=0;j<=n;j++) //DP if(arr[i][j]!=-1) { if(i && arr[i-1][j]!=-1) arr[i][j]+=arr[i-1][j]; if(j && arr[i][j-1]!=-1) arr[i][j]+=arr[i][j-1]; } } int main() { // m,n為目的坐標 a,b為馬的位置 int a,b; cin>>m>>n>>a>>b; arr[a][b]=-1; arr[a+1][b+2]=-1; arr[a][b]=-1; if(a-1>=0) arr[a-1][b+2]=-1; arr[a+2][b+1]=-1; if(a-2>=0) arr[a-2][b+1]=-1; if(b-1>=0) arr[a+2][b-1]=-1; if(a-2>=0 && b-1>=0) arr[a-2][b-1]=-1; if(b-2>=0) arr[a+1][b-2]=-1; if(a-1>=0 && b-2>=0)arr[a-1][b-2]=-1; dp(); cout<<arr[m][n]<<endl; }
【動態規劃】洛谷-過河卒