您的位置:首页 > 编程语言 > Java开发

跳跃版图 java 大整数 记忆化搜索 dp

2020-04-07 18:31 1731 查看

题目描述

有一个 n×n 的格子,每个格子中有一个非负整数。你的目标是从左上角跳到右下角,每步只能向右或向下跳。格子中的数代表从该格开始跳跃的前进步数,如果某次跳跃会跃出格子 界限则该跳跃是禁止的。注意 0 是一个绝对终点,因为从这里无法再移动。


你的任务是统计有多少种合法路径。上图 1 中共有 3 种路径,分别表示在图 2 中。

输入
第一行,一个整数 n(3 ≤ n ≤ 100)。

接下来 n 行 n 列,表示格子中的数,所有数的范围在[0,9]中,两个数之间用一个空格隔开。

输出

第一行,从左上角到右下角的合法路径数目。

样例输入
4
2 3 3 1
1 2 1 3
1 2 3 1
3 1 1 0

样例输出
3

思路

裸记忆化搜索,从(1,1)开始朝两个方向深度优先搜索,搜索完一个节点之后,然后用一个DP数组存储即可,但是得注意对终点(mp[i][j] == 0)的特判退出情况,否则会爆栈。

代码

import java.util.Scanner;
import java.math.BigInteger;

public class Main {
static BigInteger dp[][]=new BigInteger[110][110];
static int[][] mp=new int[110][110];
static int dir[][]=new int[2][2];
static int n;

static BigInteger dfs(int x,int y){
if(dp[x][y].compareTo(BigInteger.ZERO)>0) return dp[x][y];
for(int i=0;i<2;i++){
int xx=dir[i][0]*mp[x][y]+x;
int yy=dir[i][1]*mp[x][y]+y;
if(x==xx&&y==yy) return BigInteger.ZERO;
else if(xx==n&&yy==n){
dp[x][y]=dp[x][y].add(BigInteger.ONE);
continue;
}
if(xx>=1&&xx<=n&&yy>=1&&yy<=n)
dp[x][y]=dp[x][y].add(dfs(xx,yy));
}
return dp[x][y];
}

public static void main(String[] args) {
Scanner scan =new Scanner (System.in);
while(scan.hasNext()) {
n=scan.nextInt();
for(int i=1;i<=n;i++) {
for (int j=1; j<=n;j++) {
mp[i][j]=scan.nextInt();
}
}
dir[0][1]=dir[1][0]=1;
dir[0][0]=dir[1][1]=0;
for(int i=1;i<=n;i++) {
for(int j=1;j<=n;j++) {
dp[i][j]=BigInteger.ZERO;
}
}
dfs(1,1);
System.out.println(dp[1][1]);
}

}
}
学如逆水行舟,不进则退
  • 点赞 1
  • 收藏
  • 分享
  • 文章举报
一百个Chocolate 博客专家 发布了600 篇原创文章 · 获赞 2156 · 访问量 34万+ 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: