1. 程式人生 > 其它 >P1002 [NOIP2002 普及組] 過河卒 【記搜】

P1002 [NOIP2002 普及組] 過河卒 【記搜】

洛谷 P1002 -> Click Here

題意

從地圖左上角,只能朝下和朝右移動,問移動到地圖右下角有多少條路徑(中間有一些點不能經過(詳情間洛谷題面

思路

記憶化搜尋

\(f[i][j]\) :點 \((i,j)\) 移動到右下角有多少條路徑

\((0,0)\) 開始向右向下搜尋,若目標點 \(f\) 已經存在,直接返回即可

code

#include<iostream>
#include<map>
using namespace std;
typedef long long ll;//小坑點 開long long
ll n,m,my,mx;
map<ll,map<ll,ll> >mp;
ll f[1005][1005];
void init(){//不能經過的點
	mp[my][mx]=1;
	mp[my+2][mx+1]=1;
	mp[my+2][mx-1]=1;
	mp[my+1][mx+2]=1;
	mp[my+1][mx-2]=1;
	mp[my-1][mx+2]=1;
	mp[my-1][mx-2]=1;
	mp[my-2][mx-1]=1;
	mp[my-2][mx+1]=1;
}
bool pan(ll y,ll x){
	if(y<=n&&x<=m&&mp[y][x]==0) return true;
	return false;
}
ll dfs(ll y,ll x){
	if(f[y][x]) return f[y][x];//如果已經搜尋過此點則直接返回此點的答案
	if(pan(y+1,x)) f[y][x]+=dfs(y+1,x);//向下搜尋
	if(pan(y,x+1)) f[y][x]+=dfs(y,x+1);//向右搜尋
	return f[y][x];
}
int main(){
	cin>>n>>m>>my>>mx;
	init();
	f[n][m]=1;//初始化右下角的點,以累加路徑條數
	dfs(0,0);
	cout<<f[0][0]<<endl;
	return 0;
}