DP-牛客寒假集训营3-牛牛的DRB迷宫I
题目:
题意:
求 迷 宫 问 题 的 方 案 数 量 。 与 — — 求迷宫问题的方案数量。与—— 求迷宫问题的方案数量。与——DP题型总结 中 的 《 摘 花 生 》 类 似 。 中的《摘花生》类似。 中的《摘花生》类似。
暴 搜 三 个 分 支 指 数 级 别 的 复 杂 度 必 然 会 T 暴搜三个分支指数级别的复杂度必然会T 暴搜三个分支指数级别的复杂度必然会T
一 、 记 忆 化 搜 索 : 一、记忆化搜索: 一、记忆化搜索:
每 个 点 只 递 归 一 次 用 数 组 d p 来 保 存 , 当 再 次 搜 索 这 个 点 的 时 候 可 以 直 接 返 回 值 无 序 递 归 。 每个点只递归一次用数组dp来保存,当再次搜索这个点的时候可以直接返回值无序递归。 每个点只递归一次用数组dp来保存,当再次搜索这个点的时候可以直接返回值无序递归。
#include<bits/stdc++.h>
using namespace std;
const int MAXN=55;
const long long mod=1e9+7;
int n,m;
char s[MAXN][MAXN];
long long dp[MAXN][MAXN];
long long dp_dfs(int x,int y)
{
if(x>n||y>m)return 0;
if(dp[x][y]!=-1)return dp[x][y];
if(s[x][y]=='D')return dp[x][y]=dp_dfs(x+1,y);
if(s[x][y]=='R')return dp[x][y]=dp_dfs(x,y+1);
if(s[x][y]=='B')return dp[x][y]=(dp_dfs(x+1,y)+dp_dfs(x,y+1))%mod;
}
int main()
{
scanf("%d %d",&n,&m);
memset(dp,-1,sizeof(dp));
dp[n][m]=1;
for(int i=1;i<=n;++i)
{
scanf("%s",s[i]+1);
}
printf("%lld\n",dp_dfs(1,1));
return 0;
}
二 、 递 推 写 法 : 二、递推写法: 二、递推写法:
按 照 递 归 写 法 写 D P : d p [ i ] [ j ] 从 ( i , j ) 位 置 走 到 ( n , m ) 位 置 的 方 案 数 。 则 d p [ n ] [ m ] = 1 。 按照递归写法写DP:dp[i][j]从(i,j)位置走到(n,m)位置的方案数。则dp[n][m]=1。 按照递归写法写DP:dp[i][j]从(i,j)位置走到(n,m)位置的方案数。则dp[n][m]=1。
①
、
m
p
[
i
]
[
j
]
=
R
:
d
p
[
i
]
[
j
]
=
d
p
[
i
]
[
j
+
1
]
①、mp[i][j]=R:dp[i][j]=dp[i][j+1]
①、mp[i][j]=R:dp[i][j]=dp[i][j+1]
②
、
m
p
[
i
]
[
j
]
=
D
:
d
p
[
i
]
[
j
]
=
d
p
[
i
+
1
]
[
j
]
②、mp[i][j]=D:dp[i][j]=dp[i+1][j]
②、mp[i][j]=D:dp[i][j]=dp[i+1][j]
③
、
m
p
[
i
]
[
j
]
=
R
:
d
p
[
i
]
[
j
]
=
d
p
[
i
+
1
]
[
j
]
+
d
p
[
i
]
[
j
+
1
]
③、mp[i][j]=R:dp[i][j]=dp[i+1][j]+dp[i][j+1]
③、mp[i][j]=R:dp[i][j]=dp[i+1][j]+dp[i][j+1]
代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll mod=1e9+7;
const int maxn=55;
int n,m;
char mp[maxn][maxn];
ll dp[maxn][maxn];
int dfs(int x,int y)//暴搜
{
if(x<1||y<1||x>m||y>n) return 0;
if(x==n&&y==m) return 1;
if(mp[x][y]=='R') return dfs(x,y+1)%mod;
if(mp[x][y]=='D') return dfs(x+1,y)%mod;
if(mp[x][y]=='B') return (dfs(x+1,y)+dfs(x,y+1))%mod;
}
int main()
{
memset(mp,'!',sizeof(mp));
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>mp[i][j];
dp[n][m]=1;
int i,j;
for(i=n;i>=1;i--)
for(j=m;j>=1;j--)
{
if(i==n&&j==m) continue;
if(mp[i][j]=='R') dp[i][j]=dp[i][j+1]%mod;
if(mp[i][j]=='D') dp[i][j]=dp[i+1][j]%mod;
if(mp[i][j]=='B') dp[i][j]=(dp[i+1][j]+dp[i][j+1])%mod;
}
cout<<dp[1][1]%mod<<endl;
return 0;
}