题目
![在这里插入图片描述](https://img-blog.csdnimg.cn/e67103ebdecf427b89117413cf7f7ca5.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Zi_6Zeo5LiN5piv5paH5paH,size_20,color_FFFFFF,t_70,g_se,x_16)
题目要点
- 这道题目有四个变量,分别为坐标x,y和手里拿到宝物的个数sum还有手里宝物的最大值max,一个一个来变换会比较乱+慢,故这里可以使用记忆性递归,四个变量一起捆绑往下走,不用每次都计算上一步的值。
- “入口在左上角,出口在右上角”就可以知道递归的结束条件了。
- “可以拿起它,当然也可以不拿”这一步就要看代码了,挺清晰的。
- 还有一个要注意的点是,宝物的价值可能为0,故max(宝物的最大值)要设置-1为初始值,才有机会遍历到0。
- 最后输出的t要进行取模,也就是:t%1000000007
dfs框架
- 创建一个四维列表dp,同时储存4个变量x,y,sum,max(记忆性递归),只有dp被使用了才返回值(避免占用太多内存和时间)。
- 考虑何时结束一次递归:
到终点结束一次递归
这个到终点只是从某起点出发到终点的一条路径,到终点后返回值 - 过程:
向下和向右递归:
遍历所有从这个起点出发到终点的所有路径,并把过程中所有得到的t加起来,最后加起来之后的t也要返回值
(而且过程中的每种情况都有可能是最后一步,所以每种情况后面都对t取模)
代码
n, m, k = map(int, input().split())
s=[]
for i in range(n):
s.append(list(map(int, input().split())))
dp = [[[[-1]*15 for _ in range(15)]for _ in range(51)]for _ in range(51)]
def dfs(x, y, sum, max):
if dp[x][y][sum][max+1] != -1:
return dp[x][y][sum][max+1]
t = 0
if x==n-1 and y==m-1:
if s[x][y] > max:
if sum==k or sum==k-1:
t+=1
elif k==sum:
t+=1
dp[x][y][sum][max+1]=t
return dp[x][y][sum][max+1]
if x+1 < n:
if s[x][y] > max:
t += dfs(x+1, y, sum+1, s[x][y])
t%=1000000007
t += dfs(x+1, y, sum, max)
t%=1000000007
if y+1<m:
if s[x][y]>max:
t += dfs(x, y+1,sum+1,s[x][y])
t%=1000000007
t += dfs(x, y+1, sum, max)
t%=1000000007
dp[x][y][sum][max+1] = t
return dp[x][y][sum][max+1]
print(dfs(0, 0, 0, -1))