HDOJ水题集合7:记忆化搜索

举报
小哈里 发表于 2022/05/11 01:00:48 2022/05/11
【摘要】 1001 猫和老鼠(4) Time Limit : 2000/1000ms (Java/Other) Memory Limit : 512000/512000K (Java/Other) Total S...

1001 猫和老鼠(4)

Time Limit : 2000/1000ms (Java/Other) Memory Limit : 512000/512000K (Java/Other)
Total Submission(s) : 33 Accepted Submission(s) : 16
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
有个小老鼠在校园里收藏了一些它最爱吃的奶酪。
校园可以看成一个长度为n的正方形网格,每个网格可以标记为(p,q),其中,0 <= p , q < n. 每个网格都有一个洞,里面储存了k(0<=k<=100)块奶酪。

现在,小老鼠准备享用这些美味啦。

开始的时候,他在(0,0)这个位置,每到一个地方,它都会吃光这个地方的奶酪,然后沿着水平或者垂直的方向到达另外一个地方。麻烦的是,有个很凶的猫总是在它的洞口附近,所以他每次最多移动K个位置,否则就会被这只猫吃掉。更糟糕的是,每在一个地方吃过奶酪,小老鼠都会变胖,所以,为了获得足够下一次逃跑的能量,它每次只能去比当前位置的奶酪更多的格子。
现在已知n和k,以及在每个网格的洞中小老鼠储存的奶酪的数量,请计算小老鼠在无法移动之前,一共最多能吃到多少块奶酪。
Input
题目包含多组测试数据。

每组测试数据组成如下:
首先一行包含2个不超过100的正整数n和k;
接下来n行,每行包含n个数:
第一行n个数分别表示 (0,0) (0,1) … (0,n-1)这些位置储存的奶酪数量;
第二行n个数分别表示(1,0), (1,1), … (1,n-1)这些位置储存的奶酪数量;
以此类推。

输入数据以两个-1结束。
Output
请输出小老鼠最多 能够吃到的奶酪数量,每组数据输出一行。
Sample Input
3 1
1 2 5
10 11 6
12 12 7
-1 -1
Sample Output
37

//f[x][y]:从x,y出发能吃到的最多的奶酪
#include <bits/stdc++.h>
using namespace std;
const int maxn = 110;

int n, k, a[maxn][maxn];
int f[maxn][maxn];

int dx[] = {1,-1,0,0};
int dy[] = {0,0,1,-1};
int dfs(int x,int y){
	if(f[x][y])return f[x][y];
	f[x][y] = a[x][y];
	for(int i = 1; i <= k; i++){
		for(int j = 0; j < 4; j++){
			int nx = x+dx[j]*i, ny = y+dy[j]*i;
			if(nx>=0&&nx<=n-1&&ny>=0&&ny<=n-1&&a[nx][ny]>a[x][y]){
				f[x][y] = max(f[x][y], a[x][y]+dfs(nx,ny));
			}
		}
	}
	return f[x][y];
}

int main(){
	while(cin>>n>>k &&n!=-1&&k!=-1){
		memset(f,0,sizeof(f));
		for(int i = 0; i < n; i++)
			for(int j = 0; j < n; j++)
				cin>>a[i][j];
		cout<<dfs(0,0)<<"\n";
	}
	return 0;
}


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

1002 How many ways

Time Limit : 3000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 21 Accepted Submission(s) : 17
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
这是一个简单的生存游戏,你控制一个机器人从一个棋盘的起始点(1,1)走到棋盘的终点(n,m)。游戏的规则描述如下:
1.机器人一开始在棋盘的起始点并有起始点所标有的能量。
2.机器人只能向右或者向下走,并且每走一步消耗一单位能量。
3.机器人不能在原地停留。
4.当机器人选择了一条可行路径后,当他走到这条路径的终点时,他将只有终点所标记的能量。

如上图,机器人一开始在(1,1)点,并拥有4单位能量,蓝色方块表示他所能到达的点,如果他在这次路径选择中选择的终点是(2,4)

点,当他到达(2,4)点时将拥有1单位的能量,并开始下一次路径选择,直到到达(6,6)点。
我们的问题是机器人有多少种方式从起点走到终点。这可能是一个很大的数,输出的结果对10000取模。
Input
第一行输入一个整数T,表示数据的组数。
对于每一组数据第一行输入两个整数n,m(1 <= n,m <= 100)。表示棋盘的大小。接下来输入n行,每行m个整数e(0 <= e < 20)。
Output
对于每一组数据输出方式总数对10000取模的结果.
Sample Input
1
6 6
4 5 6 6 4 3
2 2 3 1 7 2
1 1 4 6 2 7
5 8 4 3 9 5
7 6 6 2 1 5
3 1 1 3 7 2
Sample Output
3948
Author
xhd
Source
2008杭电集训队选拔赛

//f[x][y]:从x,y出发到达n,m的路径数量
#include <bits/stdc++.h>
using namespace std;
const int maxn = 110, mod=10000;

int n, m, a[maxn][maxn];
int f[maxn][maxn];

int dfs(int x,int y){
	if(f[x][y]!=-1)return f[x][y];
	f[x][y] = 0;
	for(int i = 0; i <= a[x][y]; i++){
		for(int j = 0; j <= a[x][y]-i; j++){
			int nx = x+i, ny = y+j;
			if(nx<=n&&ny<=m){
				f[x][y] = (f[x][y]+dfs(nx,ny))%mod;
			}
		}
	}
	return f[x][y];
}

int main(){
	int T;  cin>>T;
	while(T--){
		memset(f,-1,sizeof(f));//e可能为0
		cin>>n>>m;
		f[n][m] = 1;
		for(int i = 1; i <= n; i++)
			for(int j = 1; j <= m; j++)
				cin>>a[i][j];
		cout<<dfs(1,1)<<"\n";
	}
	return 0;
}


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

文章来源: gwj1314.blog.csdn.net,作者:小哈里,版权归原作者所有,如需转载,请联系作者。

原文链接:gwj1314.blog.csdn.net/article/details/115710269

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。