Leetcode 3509. Maximum Product of Subsequences With an Alternating Sum Equal to K

1. 解题思路

这一题思路上还是一个比较直接的动态规划的思路。

我们可以快速给出动态规划的迭代函数的伪代码如下:

def dp(idx, is_even, _sum, _prod):
    nonlocal ans
    if idx >= n:
        return
    nxt_sum = _sum + nums[idx] if is_even else _sum - nums[idx]
    if nxt_sum == k and _prod * nums[idx] <= limit:
        ans = max(ans, _prod * nums[idx])
    dp(idx+1, not is_even, nxt_sum, _prod*nums[idx])
    dp(idx+1, is_even, _sum, _prod)
    return

但是,如果直接使用上述函数的话会出现超时的情况,因此,我们就需要在上述迭代函数当中进行大量的剪枝。

这里,我给到的一些剪枝条件如下:

  1. 如果当前的prod为0,且当前已经获得了一个非零的答案,那么可以不再继续迭代了,因为后续乘积必然一直为0了;
  2. 如果当前prod已经大于limit了,且当前已经获得了一个非零的答案,那么可以不再继续迭代了,因为后续乘积必然要么为0,要么一直大于limit,不符合条件了;
  3. 如果当前prod小于已有的最大的ans,且prod*2就大于limit的情况下,同样可以停止迭代了,因为后续不可能存在一种情况获得一个大于ans且小于limit的满足条件的乘积了;
  4. 如果当前位置之后能获得的最大的和小于k,或者能获得的最小的和小于k,那么同样可以停止迭代了,因为后续不可能获得满足限定条件的乘积了;
  5. 如果当前已经有了一个非零的满足条件的乘积了,那么就不需要考虑那些零元素被选取的情况了,因为他们会导致乘积一定变为0;

2. 代码实现

给出剪枝之后的最终python代码实现如下:

class Solution:
    def maxProduct(self, nums: List[int], k: int, limit: int) -> int:
        
        n = len(nums)
        ans = -1
        
        upper_bounds = [x for x in nums]
        lower_bounds = [x for x in nums]
        lower_bounds[-1] = 0
        for i in range(n-2, -1, -1):
            upper_bounds[i] = max(upper_bounds[i] - lower_bounds[i+1], upper_bounds[i], upper_bounds[i+1])
            lower_bounds[i] = min(lower_bounds[i], lower_bounds[i] - upper_bounds[i+1], lower_bounds[i+1])
        
        @lru_cache(maxsize=1000000)
        def dp(idx, is_even, s, prod):
            nonlocal ans, upper_bounds, lower_bounds
            if idx >= n:
                return
            if prod == 0 and ans != -1:
                return
            if prod > limit and ans != -1:
                return
            if prod <= ans and prod * 2 > limit:
                return
            if is_even and s + upper_bounds[idx] < k:
                return
            elif (not is_even) and s - upper_bounds[idx] > k:
                return
            nxt_sum = s + nums[idx] if is_even else s - nums[idx]
            if nxt_sum == k and prod * nums[idx] <= limit:
                ans = max(ans, prod * nums[idx])
            if ans == -1 or nums[idx] != 0:
                dp(idx+1, not is_even, nxt_sum, prod*nums[idx])
            dp(idx+1, is_even, s, prod)
            return
        
        dp(0, True, 0, 1)
        return ans

提交代码评测得到:耗时602ms,占用内存281.8MB。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值