How many ways HDU - 1978(DP 或 记忆化搜索)

26 篇文章 0 订阅
10 篇文章 0 订阅

How many ways

HDU - 1978
题意:n*m的棋盘, 机器人由左上角走到右下角, 规则如下:
1.机器人一开始在棋盘的起始点并有起始点所标有的能量。
2.机器人只能向右或者向下走,并且每走一步消耗一单位能量。
3.机器人不能在原地停留。
4.当机器人选择了一条可行路径后,当他走到这条路径的终点时,他将只有终点所标记的能量。
两个方法, 本质一样, 写法不同;
1.动态规划;左上角为1;每次找能走到的, 累加, 输出右下角;
#include <cstdio>
#include <cstring>
int a[110][110], dp[110][110];
int main(){
	int T;
	scanf("%d", &T);
	while(T--){
		int n, m;
		scanf("%d%d", &n, &m);
		for(int i=0; i<n; i++){
			for(int j=0; j<m; j++){
				scanf("%d", &a[i][j]);
			}
		}
		memset(dp, 0, sizeof(dp));
		dp[0][0]=1;
		for(int i=0; i<n; i++){
			for(int j=0; j<m; j++){
				if(dp[i][j]){
					int t=a[i][j];
					for(int x=0; x<=t; x++){
						for(int y=0; y<=t; y++){
							if(x+y==0) continue;
							if(x+y>t) break;
							int tx, ty;
							tx=x+i;
							ty=y+j;
							if(tx>=n||ty>=m) continue;
							dp[tx][ty]+=dp[i][j];
							dp[tx][ty]%=10000;
						}
					}
				}
			}
		}
		printf("%d\n", dp[n-1][m-1]%10000);
	}
	return 0;
}
2.记忆化搜索,初始化全为-1,  右下角为1, 由左上角开始, 搜到不为-1的就return;
并在过程中改写mark;
#include <cstdio>
#include <cstring>
int a[110][110], mark[110][110];	
int n, m;
int dfs(int x, int y){
	if(mark[x][y]!=-1) return mark[x][y]; 	 	
	int t, x1, y1;
	int temp=0;
	t=a[x][y];
	for(x1=0; x1<=t; x1++){
		if(x+x1>=n) break;
		for(y1=0; y1<=t; y1++){
			if(y1+y>=m) break;
			if(x1+y1>t) break;
			if(x1+y1==0) continue;
			temp+=dfs(x1+x, y1+y);
		}
	}
	temp%=10000;
	return mark[x][y]=temp; 
}
int main(){
	int T;
	scanf("%d", &T);
	while(T--){
		scanf("%d%d", &n, &m);
		for(int i=0; i<n; i++){
			for(int j=0; j<m; j++){
				scanf("%d", &a[i][j]);
				mark[i][j]=-1;
			}
		}
		mark[n-1][m-1]=1;
		printf("%d\n", dfs(0, 0));
	}
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值