信息学奥赛一本通 1194:移动路线 | OpenJudge NOI 2.6 2718:移动路线
生活随笔
收集整理的這篇文章主要介紹了
信息学奥赛一本通 1194:移动路线 | OpenJudge NOI 2.6 2718:移动路线
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
【題目鏈接】
ybt 1194:移動路線
OpenJudge NOI 2.6 2718:移動路線
【題目考點】
1. 坐標型動態規劃
【解題思路】
解法1:遞推
設狀態數組dp,dp[i][j]表示從(1,1)到(i,j)的路徑條數。
考慮螞蟻到(i,j)位置前可能是哪里,把可能的到(i,j)的前一個位置的路徑數量加和,即為到(i,j)的路徑數量。
- 如果(i,j)是(1,1),起始位置到起始位置的路徑數量為1,所以:dp[1][1]=1;
- 如果是在第1行,即i為1,那么只能沿著第一行走到(i,j),只有一種走法。所以如果i為1:dp[i][j] = 1;
- 如果是在第1列,即j為1,那么只能沿著第一列走到(i,j),只有一種走法。所以如果j為1:dp[i][j] = 1;
- 除了上述情況,到(i,j)的前一個位置只能是它下面的位置(i-1,j)和左邊的位置(i,j-1),所以:dp[i][j] = dp[i-1][j]+dp[i][j-1];
遍歷二維數組dp,按照上述遞推關系做遞推。最后輸出dp[n][m]。
解法2:遞推 借助下標為0的位置
與解法1思路相同。將數組各元素初始化為0,首先設初始值a[1][1] = 1;,循環時只使用遞推關系,會讓下標為0的位置參與運算。
已知遞推關系:dp[i][j] = dp[i-1][j]+dp[i][j-1],
- 如果i為1,那么dp[1][j] = dp[0][j] + dp[1][j-1] = dp[1][j-1]。
- 如果j為1,那么dp[i][1] = dp[i-1][1] + dp[i][0] = dp[i-1][1]。
解法3:記憶化遞歸
思路與上述解法相似。
【題解代碼】
解法1:遞推
#include <bits/stdc++.h> using namespace std; int main() {int m, n, dp[25][25];cin >> m >> n;for(int i = 1; i <= m; ++i)for(int j = 1; j <= n; ++j){if(i == 1 || j == 1)//第一行或第一列,路線數都是1 dp[i][j] = 1;elsedp[i][j] = dp[i][j-1] + dp[i-1][j];}cout << dp[m][n];return 0; }解法2:遞推 借助下標為0的位置
#include <bits/stdc++.h> using namespace std; int main() {int m, n, dp[25][25] = {};cin >> m >> n;dp[1][1] = 1; for(int i = 1; i <= m; ++i)for(int j = 1; j <= n; ++j)if(i != 1 || j != 1)//不在這里算dp[1][1] dp[i][j] = dp[i][j-1] + dp[i-1][j];cout << dp[m][n];return 0; }解法3:記憶化遞歸
#include <bits/stdc++.h> using namespace std; int dp[25][25]; int solve(int i, int j)//到i,j的路徑數 {if(dp[i][j] > 0)return dp[i][j];if(i == 1 || j == 1)return 1;elsereturn dp[i][j] = solve(i-1, j) + solve(i, j-1); } int main() {int m, n;cin >> m >> n;cout << solve(m, n);return 0; }總結
以上是生活随笔為你收集整理的信息学奥赛一本通 1194:移动路线 | OpenJudge NOI 2.6 2718:移动路线的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 对韩java_清华大学毕业的韩老师图解J
- 下一篇: 信息学奥赛一本通(1407:笨小猴)