【Python】蓝桥杯00.2

1.背包问题

题目如下

        该题是经典的背包问题,可以设计一个计算的函数采用递归的思想解决,函数的思路首先判断,V和N是否等于0(当然题目给出范围不可能等于0),如果等于0,则可直接输出喜爱值为0,接着判断所购买的礼物价值是否大于V,如果大于则直接跳过选着前一项礼物(由于是从最后一项开始计算),如小于则第一种情况可以选择购买,但是V得减去已花出的钱,第二种情况选择前一项礼物。两种情况的优劣可以利用max()来判断,如此进行递归,最后输出最优解。

def ks(n,c):
    if n==0 or c==0:
        result=0
    elif J[n]>c:
        result=ks(n-1,c)
    else:
        tmp1=ks(n-1,c)
        tmp2=K[n]+ks(n-1,c-J[n])
        result=max(tmp1,tmp2)
    return result

N,V = list(map(int, input().split(",")))
J=[0]
K=[0]
for i in range(N):
    J1,K1=list(map(int, input().split(",")))
    J.append(J1)
    K.append(K1)
print(ks(N,V))

2.深度优先算法(DFS)

dfs是数据结构的经典算法,这里使用计算最长递减路线来展示,存在以下列表

        要计算其中的最长递减路线,假设从左上角的1开始,则不存在下一个路径,则路线长度为1,若从右上角的3开始,则不能往下走,因为4大于3,只能往左走至1,所以路线长度为2,目的是找到最长的递减路线。

        首先可以定义函数用来计算路线,利用i,j来储存当前的位置,所以应该考虑是否有出界的现象,判断i,j是否小于0,以及如果i,j>2(因为python的特性从0开始计算)的话也是出界。还可以添加val用于判断是否有数大于其中的最大数。然后我们就可以进行上下左右的路线选择(使用递归思想)

lst=[
    [1,1,3],
    [2,3,4],
    [1,0,1]
]
m,n=3,3
def dfs(i,j,val):
    if i<0 or i==m:
        return 0
    if j<0 or j==m:
        return 0
    if lst[i][j]>=val:
        return 0
  

    res=1
    res = max(res, 1+dfs(i - 1, j, lst[i][j]))
    res = max(res, 1+dfs(i + 1, j, lst[i][j]))
    res = max(res, 1+dfs(i, j - 1, lst[i][j]))
    res = max(res, 1+dfs(i, j + 1, lst[i][j]))
 
    return res


for x in range(m):
    for y in range(n):
        res = dfs(x,y,100)
        print(res,end=" ")
    print()

计算结果如图

        这是从每点开始的递减路径,可以看出从4开始路径最长为5,我们可以创建一个字典来储存各点的结果,在使用max()算出最长路径。完整代码如下

lst=[
    [1,1,3],
    [2,3,4],
    [1,0,1]
]
m,n=3,3
def dfs(i,j,val):
    if i<0 or i==m:
        return 0
    if j<0 or j==m:
        return 0
    if lst[i][j]>=val:
        return 0
    if (i,j) in dp:
        return dp[(i,j)]

    res=1
    res = max(res, 1+dfs(i - 1, j, lst[i][j]))
    res = max(res, 1+dfs(i + 1, j, lst[i][j]))
    res = max(res, 1+dfs(i, j - 1, lst[i][j]))
    res = max(res, 1+dfs(i, j + 1, lst[i][j]))
    dp[(i,j)] = res
    return res
dp={}

for x in range(m):
    for y in range(n):
        res = dfs(x,y,100)
        print(res,end=" ")
    print()
print(max(dp.values()))

3.实例(海洋污染问题)

题目如图

        利用dfs算法可以很快的解决问题,首先遍历,如果是1则调用一次dfs,所以第一次调用在左上的1,那么调用dfs,以上下左右的顺序再次遍历将遍历到的1变为0,这样就找出第一片独立海域。再次遍历,由于之前第一片独立海域的1已经变为0,所以第二次调用dfs的位置是第二行第三列的1,如此反复,统计使用过多少次dfs,就可以算出有多少独立海域。

lst=[
    [1,1,0,0,0],
    [1,0,1,0,0],
    [1,0,0,0,0],
    [1,1,0,1,1]
]
m=4 ; n=5
def dfs(x,y):
    if x < 0 or x == m:
        return 
    if y < 0 or y == m:
        return 


    lst[x][y] = 0
    dfs(x+1,y)
    dfs(x-1,y)
    dfs(x,y-1)
    dfs(x,y+1)
    
cut=0
for i in range(m):
    for j in range(n):
        if lst[i][j]==1:
            dfs(i,j)
            cut += 1
print(cut)

        在输出结果过程中出现了如下错误RecursionError: maximum recursion depth exceeded in comparison,意思是超过了最大的遍历深度,经查找后发现少了一个关键条件,就是当lst[x][y]==0时是要退出函数的,所以正确代码如下。

lst=[
    [1,1,0,0,0],
    [1,0,1,0,0],
    [1,0,0,0,0],
    [1,1,0,1,1]
]
m=4 ; n=5
def dfs(x,y):
    if x < 0 or x == m:
        return
    if y < 0 or y == n:
        return
    if lst[x][y] == 0:
        return


    lst[x][y] = 0
    dfs(x+1,y)
    dfs(x-1,y)
    dfs(x,y-1)
    dfs(x,y+1)
cut=0
for i in range(m):
    for j in range(n):
        if lst[i][j]==1:
            dfs(i,j)
            cut+=1
print(cut)

  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值