跳跃版图(记忆化搜索,DP)

来源:互联网 发布:量化分析 java python 编辑:程序博客网 时间:2024/04/29 21:50

题目描述
有一个 n×n 的格子,每个格子中有一个非负整数。你的目标是从左上角跳到右下角,每步只能向右或向下跳。格子中的数代表从该格开始跳跃的前进步数,如果某次跳跃会跃出格子界限则该跳跃是禁止的。注意 0 是一个绝对终点,因为从这里无法再移动。你的任务是统计有多少种合法路径。
数据规模
3<=n<=100。
思路
这个题是一个比较裸的记忆化搜索,从(1,1)开始朝两个方向深度优先搜索,搜索完一个节点之后,然后用一个DP数组存储即可,注意aij=0的特判退出情况,否则会爆栈。
代码

#include<iostream>#include<cstdio>#include<cstdlib>using namespace std;int i,j,m,n;long long dp[101][101];int a[101][101];int mo[3][2]={{1,0},{0,1}};int r(){    int ans=0,f=1;    char ch;    while(ch<'0'||ch>'9')    {        if(ch=='-')        f=-1;        ch=getchar();    }    while(ch>='0'&&ch<='9')    {        ans*=10;        ans+=ch-'0';        ch=getchar();    }    return ans*f;}long long dfs(int x,int y){    if(dp[x][y]) return dp[x][y];    int nx,ny;    for(int i=0;i<2;i++)    {        nx=mo[i][0]*a[x][y]+x;        ny=mo[i][1]*a[x][y]+y;        if(x==nx&&y==ny)        return 0;        else if(nx==n&&ny==n)        {             dp[x][y]++;            continue;        }        else if(nx>0&&nx<=n&&ny>0&&ny<=n)        {            dp[x][y]+=dfs(nx,ny);        }    }    return dp[x][y];}int main(){    freopen("jump.in","r",stdin);    freopen("jump.out","w",stdout);    n=r();    for(i=1;i<=n;i++)    for(j=1;j<=n;j++)    {        a[i][j]=r();    }    dfs(1,1);    cout<<dp[1][1];}/*61 1 1 1 1 11 1 1 1 1 11 1 1 1 1 11 1 1 1 1 11 1 1 1 1 11 1 1 1 1 0*/

这里写图片描述