leetcode 面试题 17.16. 按摩师

https://leetcode-cn.com/problems/the-masseuse-lcci/

这道题和198. 打家劫舍 一样的
leetcode 面试题 17.16. 按摩师_第1张图片

其实这道题和之前做过的 300.最长上升子序列 很像

这道题解法非常多啊

动态规划

我们设dp[i]为以i为终点的最大值,dp初始为nums
又由于不能连续选择,则dp[i]一定和dp[i-1]无关
为了得到最大值,我们必须从[0,i-1)遍历dp,记录最大值,然后更新dp[i]=dp[i]+max
最后返回max(dp)就行了

class Solution:
    def massage(self, nums: List[int]) -> int:
        if not nums:
            return 0
        dp=nums
        for i in range(len(nums)):
            tmax=0
            for j in range(0,i-1):
                if dp[j]>tmax:
                    tmax=dp[j]
            dp[i]=dp[i]+tmax
        return max(dp)

leetcode 面试题 17.16. 按摩师_第2张图片
这个执行效率说明应该有更好的方法

DFS

尝试一下DFS解法,直接DFS的话应该会超时,要加上剪枝
这个裸的DFS超时了

class Solution:
    def massage(self, nums: List[int]) -> int:
        if not nums:
            return 0
        self.ans=0
        self.dfs(0,0,nums)
        return self.ans 
    
    def dfs(self,ind,temp,nums):
        if ind>=len(nums):
            self.ans=max(self.ans,temp)
            return
        # 选择
        self.dfs(ind+2,temp+nums[ind],nums)
        # 不选
        self.dfs(ind+1,temp,nums)

数据量其实并不大

[183,219,57,193,94,233,202,154,65,240,97,234,100,249,186,66,90,238,168,128,177,235,50,81,185,165,217,207,88,80,112,78,135,62,228,247,211]

麻烦的就是剪枝条件怎么找出来,尝试一个非常粗糙的剪枝,就是如果选择了当前的元素,之后的元素总和都不大于的ans话就不选择了

        if temp+nums[ind]+sum(nums[ind+2:])>self.ans:
            # 选择
            self.dfs(ind+2,temp+nums[ind],nums)
        # 不选
        self.dfs(ind+1,temp,nums)

感觉更暴力了,又卡在了一个更长的样例

看了下提示有打表法,还有记忆化搜索,想不出来…
看了一眼评论区和题解几乎都是清一色的DP,今天就先到这里吧,不想写了。。

你可能感兴趣的:(leetcode)