帕斯卡游记(记忆化dfs)

问题描述
nxn游戏板上装有整数,每平方一个非负整数。目标是沿着板子的左上角到右下角的任何合法路径行进。任何一个正方形中的整数表示距该位置必须多大的步幅。如果步长将提前离开游戏板,则禁止沿该特定方向前进。所有步骤都必须在右侧或底部。请注意,0是一个死角,会阻止进一步的进展。

考虑图1所示的4 x 4板,其中实心圆圈标识起始位置,而虚线圆圈标识目标。图2显示了从起点到目标的三个路径,每个路径中不相关的数字都已删除。

图1

在这里插入图片描述
图2
在这里插入图片描述

输入值
输入包含1到30个板的数据,最后一行仅包含整数-1。电路板的数据从包含单个正整数n(4 <= n <= 34)的行开始,n是该电路板中的行数。随后是n行数据。每行包含n个数字,0-9,中间没有空格。

输出量
每个板的输出由一行组成,包含一个整数,该整数是从左上角到右下角的路径数。任何一块板的路径将少于2 ^ 63。

样本输入
4
2331
1213
1231
3110
4
3332
1213
1232
2120
5
11101
01111
11111
11101
11101
-1

样本输出
3
0
7

[提示]提示[/提示]
检查每条路径的蛮力方法可能会超过分配的时间限制。
使用Visual C / C ++可以将64位整数值用作“ __int64”值或“ long long”值
使用Free Pascal编译器使用GNU C / C ++或“ int64”值。

资源
美国中部,2005年

  • 题意每次只能向下或向右走当前值的步数
  • 问有多少种方法
#include<bits/stdc++.h>
using namespace std;
int n;
int mp[50][50];
long long ans[50][50];
int dir[4][2] = {{1,0},{0,1}};
long long dfs(int x, int y){
	if(ans[x][y] >= 0)return ans[x][y];
	ans[x][y] = 0;
	for(int i = 0; i < 2; i ++){
		int tx = x + dir[i][0] * mp[x][y];
		int ty = y + dir[i][1] * mp[x][y];
		if(tx > 0 && ty > 0 && tx <= n && ty <= n)
			ans[x][y] += dfs(tx, ty);
	}
	return ans[x][y];
}
int main(){
	ios::sync_with_stdio(false);
    while(cin >> n){
    	if(n == -1)break;
    	memset(mp,0,sizeof(mp));
    	memset(ans,-1,sizeof(ans));
    	string k;
    	for(int i = 1; i <= n; i ++){
    		int temp = n;
    		cin >> k;
    		while(temp){
    			mp[i][temp] = (k[temp - 1] - '0') % 10;
    			temp --;
			}
		}
		ans[n][n] = 1;
		cout << dfs(1, 1) << endl;
	}
	return 0;
} 

发布了46 篇原创文章 · 获赞 5 · 访问量 2664

猜你喜欢

转载自blog.csdn.net/xuhang513/article/details/104976498