NOIP 2002 過河卒(DP遞推)

2021-09-19 14:07:59 字數 1737 閱讀 9094

棋盤上a點有乙個過河卒,需要走到目標b點。卒行走的規則:可以向下、或者向右。同時在棋盤上c點有乙個對方的馬,該馬所在的點和所有跳躍一步可達的點稱為對方馬的控制點。因此稱之為「馬攔過河卒」。

棋盤用座標表示,a點(0, 0)、bb點(n, m)(n, m為不超過2020的整數),同樣馬的位置座標是需要給出的。

現在要求你計算出卒從a點能夠到達b點的路徑的條數,假設馬的位置是固定不動的,並不是卒走一步馬走一步。

輸入格式:

一行四個資料,分別表示b點座標和馬的座標。

輸出格式:

乙個資料,表示所有的路徑條數。

輸入樣例#1:複製

6 6 3 3
輸出樣例#1:複製

6
結果可能很大!

策略:使用動態規劃把整張圖的步數全部打出(資料範圍很小,這是可行的)。

為了防止陣列越界等一系列不必要的麻煩,在這裡把(1,1)當作初始位置,也就是說全體座標自增1.

把馬自身所在的位置和其能達到的八個位置全部標記,這些路都不通。

由於我們是要統計路徑數,所以它的起始點天然具有一條長度為0的路徑,即dp[1][1]=1(初始化)

由於這個卒只能朝右和朝下走,所以對於棋盤上非左部邊界或頂部邊界的任意乙個點而言,如果棋子到了這裡,那麼它一定是從左方或是上方到來的。於是有遞推公式:

由於在實際操作過程中可能有資料覆蓋等情況,所以這裡用狀態轉移方程代替普通的遞推式

#include #include #include #include #include #include #include #define determination main

#define lldin(a) scanf("%lld",&a)

#define din(a) scanf("%d",&a)

#define printlnlld(a) printf("%lld\n",a)

#define printlnd(a) printf("%d\n",a)

#define printlld(a) printf("%lld",a)

#define printd(a) printf("%d",a)

#define reset(a,b) memset(a,b,sizeof(a))

const int inf=0x3f3f3f3f;

using namespace std;

const double pi=acos(-1);

typedef long long ll;

typedef long double ld;

///schlacht von stalingrad

/**although there will be many obstructs ahead,

the desire for victory still fills you with determination..**/

bool vis[75][75];

ll directions[8][2]= ;//馬可以到的地方

unsigned long long dp[99][99];//資料很大,用unsigned long long 可以滿足.

int determination()

cout<

return 0;

}

遞推2 過河卒(Noip2002)

寫出遞推公式就ok了,具體程式設計還是很簡單的 過河卒 noip2002 問題描述 棋盤上a點有乙個過河卒,需要走到目標b點。卒行走的規則 可以向下 或者向右。同時在棋盤上c點有乙個對方的馬,該馬所在的點和所有跳躍一步可達的點稱為對方馬的控制點。因此稱之為 馬攔過河卒 棋盤用座標表示,a點 0,0 ...

noip2002 普及組 過河卒

題目描述 棋盤上a點有乙個過河卒,需要走到目標b點。卒行走的規則 可以向下 或者向右。同時在棋盤上c點有乙個對方的馬,該馬所在的點和所有跳躍一步可達的點稱為對方馬的控制點。因此稱之為 馬攔過河卒 棋盤用座標表示,a點 0,0 b點 n,m n,m為不超過20的整數 同樣馬的位置座標是需要給出的。現在...

NOIP 2002普及組 過河卒詳解

本文引用自 kcfzyhq 的部落格 首先我們來看看下面這個圖,這個圖基本表現了題目的意思 乙個卒要從圖的左上角a點走到右下角b點,而其中有一點c為馬的位置,c與其周邊馬能走到的p1 p8點共9個點是不能走的,問有多少種從a走到b的方法 我們可以先把這個問題當數學問題來考慮相信許多朋友以前都遇到過類...