版权声明:署名,允许他人基于本文进行创作,且必须基于与原先许可协议相同的许可协议分发本文 (Creative Commons)
题目链接:https://cn.vjudge.net/contest/306123#problem/A
题目解析 地图为n*n,从左上角走到右下角,只能向右和向下,遇到括号里的数字是几就走几步,0除外(0是一个死胡同,不能走了),求有几种方法?
下图很好的说明了从起点到终点的路径
注: 地图也是相当大的,若一个一个搜,容易超时,就需要优化----->把搜过的点的数据保留下来,下一次搜到这一点的时候直接用保留下来的数据。避免了重复操作(专业术语:记忆化搜索)。把每一点的状态保留下来,说明了此搜索与dp密不可分。
对于这道题的细节
(1)调用dfs时,long long每次都要写。
(2)这道题只能往右和往下,这道题对坐标的处理也是需要积累的。
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
long long s;
int to[2][2]={1,0,0,1},n;
long long dp[50][50];//dp[i][j]:记录(i,j)到终点的路径
char a[50][50];
long long dfs(int x,int y){
int flag=0;
long long s=0;//这个地方long long必须写,可能数据过大,题目中大致可能也是这个意思
if(dp[x][y]!=-1)
return dp[x][y];
if(x==n-1&&y==n-1) //目标状态
return 1; //路径加1
if(a[x][y]=='0') {
dp[x][y]=0; //对零的特判
return 0;
}
for(int i=0; i<2; i++){
int tx=(a[x][y]-'0')*to[i][0]+x; //下一点的坐标
int ty=(a[x][y]-'0')*to[i][1]+y;
if(tx>=0&&tx<n&&ty>=0&&ty<n){
flag=1;
s=s+dfs(tx,ty);
}
}//一个点搜到不能再搜了,才执行下面的if选择句
if(flag==0) //这一点向右和向左都无法走
{
dp[x][y]=0;
return dp[x][y];
}
else
{
dp[x][y]=s;
return dp[x][y];
}
}
int main(){
while(~scanf("%d",&n)) {
if(n==-1)
break;
s=0;
for(int i=0; i<n; i++) //输入地图
scanf("%s",a[i]);
memset(dp,-1,sizeof(dp));
printf("%lld\n",dfs(0,0)); //dfs(0,0)为左上角
}
return 0;
}
不因长夜漫漫而畏惧