信息学奥赛一本通 1314:【例3.6】过河卒(Noip2002) | 1921:【02NOIP普及组】过河卒 | 洛谷 P1002 [NOIP2002 普及组] 过河卒
生活随笔
收集整理的這篇文章主要介紹了
信息学奥赛一本通 1314:【例3.6】过河卒(Noip2002) | 1921:【02NOIP普及组】过河卒 | 洛谷 P1002 [NOIP2002 普及组] 过河卒
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
【題目鏈接】
ybt 1314:【例3.6】過河卒(Noip2002)
ybt 1921:【02NOIP普及組】過河卒
洛谷 P1002 [NOIP2002 普及組] 過河卒
【題目考點】
1. 坐標型動態規劃
【解題思路】
設狀態數組dp,dp[i][j]表示從(0,0)到(i,j)的路徑條數。
考慮卒到(i,j)位置的前一個位置可能是哪里,把可能的到(i,j)的前一個位置的路徑數量加和,即為到(i,j)的路徑數量。
- 如果(i,j)是(0,0),到起始位置的路徑數量為1,所以:dp[0][0]=1;
- 如果這個位置是馬的控制點,那么到這里的路徑數量為0。
- 除了上述情況,如果是在第0行,即i為0,那么到(i,j)的前一個位置只能是(i,j-1)。所以如果i為0:dp[i][j] = dp[i][j-1];
- 除了上述情況,如果是在第0列,即j為0,那么到(i,j)的前一個位置只能是(i-1,j)。所以如果j為0:dp[i][j] = dp[i-1][j];
- 除了上述情況,到(i,j)的前一個位置只能是它上面的位置(i-1,j)和左邊的位置(i,j-1),所以:dp[i][j] = dp[i-1][j]+dp[i][j-1];
先將dp數組初始化為-1,把馬的控制點位置的值設為0。(0,0)位置設為1,而后遍歷二維數組dp,按照上述遞推關系做遞推。最后輸出dp[n][m]。
【注意】:最終結果超出了int可以表示的范圍,dp數組必須設為long long類型。
【題解代碼】
解法1:遞推 用dp的值判斷一個位置是否被馬控制
dp[i][j]為0表示該位置被馬控制,為-1表示該位置尚未賦值。
#include <bits/stdc++.h> using namespace std; int dir[8][2]={{-1,2},{-1,-2},{1,2},{1,-2},{-2,1},{-2,-1},{2,1},{2,-1}};//方向數組:馬走日下一步到的位置和當前位置的坐標差值 int main() { long long dp[25][25];//dp[i][j]:表示從(0,0)到(i,j)的路徑條數。memset(dp, -1, sizeof(dp)); int n, m, cx, cy;cin >> n >> m >> cx >> cy;dp[cx][cy] = 0;//設置馬的控制點,值為0 for(int i = 0; i < 8; ++i){int x = cx + dir[i][0], y = cy + dir[i][1];if(x >= 0 && x <= n && y >= 0 && y <= m)dp[x][y] = 0;}dp[0][0] = 1;for(int i = 0; i <= n; ++i)for(int j = 0; j <= m; ++j){if(dp[i][j] == 0)//馬控制的點不做計算 continue;if(i == 0 && j == 0)dp[i][j] = 1;else if(i == 0)dp[i][j] = dp[i][j-1];else if(j == 0)dp[i][j] = dp[i-1][j];elsedp[i][j] = dp[i-1][j] + dp[i][j-1];}cout << dp[n][m];return 0; }解法2:遞推 設vis數字表示某位置是否被馬控制
vis[i][j]為真表示該位置被馬控制
#include <bits/stdc++.h> using namespace std; int dir[8][2]={{-1,2},{-1,-2},{1,2},{1,-2},{-2,1},{-2,-1},{2,1},{2,-1}};//方向數組:馬走日下一步到的位置和當前位置的坐標差值 long long dp[25][25];//dp[i][j]:表示從(0,0)到(i,j)的路徑條數。初值為0。 bool vis[25][25];//vis[i][j]:表示(i,j)位置是否被馬控制 int main() { int n, m, cx, cy;cin >> n >> m >> cx >> cy;vis[cx][cy] = true;//設置馬的控制點for(int i = 0; i < 8; ++i){int x = cx + dir[i][0], y = cy + dir[i][1];if(x >= 0 && x <= n && y >= 0 && y <= m)vis[x][y] = true;}dp[0][0] = 1;for(int i = 0; i <= n; ++i)for(int j = 0; j <= m; ++j){if(vis[i][j])//馬控制的點不做計算 continue;if(i == 0 && j == 0)dp[i][j] = 1;else if(i == 0)dp[i][j] = dp[i][j-1];else if(j == 0)dp[i][j] = dp[i-1][j];elsedp[i][j] = dp[i-1][j] + dp[i][j-1];}cout << dp[n][m];return 0; }總結
以上是生活随笔為你收集整理的信息学奥赛一本通 1314:【例3.6】过河卒(Noip2002) | 1921:【02NOIP普及组】过河卒 | 洛谷 P1002 [NOIP2002 普及组] 过河卒的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: checkbox设置三种状态 qt_Ch
- 下一篇: 信息学奥赛一本通 1308:【例1.5】