备战蓝桥杯之动态规划最后一天

今天是4/17,明天初赛,吧之前leetcode几道动态规划整理一遍
在这里插入图片描述
在这里插入图片描述
这是一道较有难度的动态规划题,之前刷了几次没写出来,现在从代码的角度做个梳理,
1.明确目标,题目问的是子集的个数,也就是说,最大有多少个数这一类问题,所以再写递归的时候,变量ans求的是个数。
2.围绕ans做思路,既然要求ans,肯定用max函数

  class Solution:
    def findMaxForm(self, strs,m,n):
        def dfs(index,m,n):
            if index==len(strs):
                return 0 
            ze=strs[index].count('0');on=strs[index].count('1');ans=0
            if ze<=m and on<=n:
                ans=1+dfs(index+1,m-ze,n-on)
            ans=max(ans,dfs(index+1,m,n))
            return ans
        return dfs(0,m,n)

在这里插入图片描述
3.获取数组索引中的零和一,这里开始因为我的思路不在长度上,我先获取最大字符串长度,然后再找他的个数,这里踩了不少坑,,
我这里看看之前的错误思路
先做两个小测试,拼接字符串和找最大值,到这里一切都正常在这里插入图片描述在这里插入图片描述
然后,写成递归后,return返回了None,说明代码里的cur出问题了,
在这里插入图片描述
再做个测试。。
cur=max(cur,dfs(cur+“1”)),这里dfs函数每次遍历都会有一个return cur的值,cur表示某个+"1"拼接字符串,但编译器返回了空。那不而了之

然后,回过头看看之前思路好的代码,ans=1+dfs(index+1,m-ze,n-on)dfs递归实现了什么? 他的值是多少?
index+1,则在继续遍历,到终止条件index==len(strs)停止,dfs遍历一次,ans的值+1,遍历两次,ans的值+2,所以,单纯的ans=dfs(index+1,m,n),值是没有+的,这用来实现不选某个数组值
ans=max(ans,dfs(index+1,m,n))。取这个元素or接着遍历
这样写,存在很多子重复问题
在这里插入图片描述

只过了将近1/3的数据,我想到用记忆化递归做数组处理,
在这里插入图片描述
然后发现 [‘10’,‘0’,‘1’]这种情况时,由于 '10’和(‘0’,‘1’)都满足情况,但不能返回最大个数,不而了之,
后来 看了某佬哥的笔记,加入@lru_cache(None),用缓存优化递归,

在这里插入图片描述
在这个基础上,看个简单的题,
在这里插入图片描述
明确目标:数组能不能分成左右两侧值相等? 能返回true,不能返回False
,那么,return False or True ,变量res存储的是0或1,,
看了某老哥的写法后,思路是取一半,target==sum/2,如果他是奇数,直接False,如果他是偶数,那可能有机会。
在这里插入图片描述
如果处理选or 不选
res=test(sum1+nums[i],i+1) or test(sum1,i+1)
注意这里不选需要前面返回False, 这里的res只能返回布尔型,配合or做选或不选,如果res不为布尔,那or失效

class Solution:
    def canPartition(self, nums):
        sum=0;arr={}
        for i in range(len(nums)):
            sum+=nums[i]
        if sum%2!=0:
            return False
        target=sum/2
        def test(sum1,index):
            if index>=len(nums) or sum1>sum/2:
                return False;
            if sum1==target:
                return True;
            for i in range(index,index+2):
        #    if (sum1,index) in arr: 
           #     return arr[(sum1,index)]
                res=test(sum1+nums[i],index+1) or test(sum1,index+1)
        #    arr[(sum1,i)]=res
            #print(arr)
                return res
        return test(0,0)

递归过了1/3的数据
在这里插入图片描述
这里要写for遍历,范围是index,index+2,这个数和后一个数,感觉没啥必要,没有用到max函数,但去掉报错了。。
记忆化递归比较好写这题,一维数组递归就行
在这里插入图片描述
数组索引这样,,,比较容易看**,值是布尔,索引是sum1**
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ECHO::

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值