【蓝桥杯】【python】地宫取宝

题目描述

代码我利用的C语言网bobby同学的,但原文没有解释,本文加上了我的一些理解,附上原文代码

https://blog.dotcpp.com/a/77354
在这里插入图片描述

整体思路

深度遍历

我的理解就是一头扎到底,一个节点继续往下走,直到走不通或达到限制要求为止

这道题目也是一样,利用一个数组存储到这个点的时候,某一个数量的宝物在确定最大价值的条件下有几种方案

记忆性递归

例如计算斐波那契数时,另外创建一个数组来存储每一个已经完成计算的斐波那契数,以便用时调用。

而普通的递归计算f(4)时还需要计算f(3)+f(2)但是计算f(3)的时候还要计算f(2)+f(1),这样重复计算f(2),导致时间花费较多

此处也是一样,利用一个四维数组,存储某一个坐标的具体信息,例如:状态列表dp[1][2][3][4]=5 表示坐标(1,2)这个点物

品数量为3最大价值为4的方案有5种

此处有点类似之前做的“危险系数”,也是利用了类似的方法

代码实现过程

1、数据的输入

在此处把状态列表dp中每个数都定义成-1

# main
n,m,k=map(int,input().split())
# 记录迷宫的宝贝价值
table=[]
for _ in range(n):
    table.append(list(map(int,input().split())))
# 状态列表dp[1][2][3][4]=5 表示坐标(1,2)这个点物品数量为3最大价值为4的方案有5种
dp=[[[[-1]*15 for _ in range(15)] for _ in range(51)]for _ in range(51)]

2、深度遍历过程

向定义的函数中传递四个数,(x, y, xum, max),也就是四维列表的四个部分,分别代表横坐标,纵坐标,现在已经拿的物品总量,其中最大价值

然后一共有四种情况

2.1、“如果这个方案先前采用过了,就会有一个值而不是初始值-1”

这也是我起初最不理解的一个地方,在另外一篇文章中看到这样的解释:“此处为什么max+1,因为题目中宝物价值是:Ci (0< =Ci< =12),包含0,所以可能取到0,那我在main函数调用时初始化max只能是负数,否则如果起始点为0,我就不能拾起了,但数组下标又不能是负数,干脆直接化为max+1,max+1>=0说明拾起第一件宝物”

我的理解:上面的解释应该是对把dp最初定义为-1的原因,但是

2.2、到达终点

达到终点又分为最后一个格子的物品可以拿和不可以拿

2.3、向下走

向下走又分为拿物品、不拿物品

2.4、向右走

向右走又分为拿物品、不拿物品

完整代码

# main
n,m,k=map(int,input().split())
# 记录迷宫的宝贝价值
table=[]
for _ in range(n):
    table.append(list(map(int,input().split())))
# 状态列表dp[1][2][3][4]=5 表示坐标(1,2)这个点物品数量为3最大价值为4的方案有5种
dp=[[[[-1]*15 for _ in range(15)] for _ in range(51)]for _ in range(51)]

#深度遍历
def dfs(x,y,sum,max):
    #因为如果这个方案先前采用了,就会有一个值而不是初始值-1
    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 table[x][y]>max:
            #可选可不选,若选那么只能再选最后一个(先前有k-1个)
            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 table[x][y]>max:
            t+=dfs(x+1,y,sum+1,table[x][y])
            t%=1000000007
        #不选
        t+=dfs(x+1,y,sum,max)
        t%=1000000007

    #向右走
    if y+1<m:
        #可选
        if table[x][y]>max:
            t+=dfs(x,y+1,sum+1,table[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]
dp[0][0][0][0]=dfs(0,0,0,-1)
print(dp[0][0][0][0])
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值