首页 > 其他分享 >【DP】乘积最大子数组

【DP】乘积最大子数组

时间:2024-05-04 23:22:19浏览次数:25  
标签:结尾 nums fmax 数组 maxF DP 乘积

题源

思路和算法

如果我们用 fmax(i) 来表示以第 i 个元素结尾的乘积最大子数组的乘积,a 表示输入参数 nums,那么根据「53. 最大子序和」的经验,我们很容易推导出这样的状态转移方程:

fmax(i) = max{f(i-1)×a[i], a[i]}

它表示以第 i 个元素结尾的乘积最大子数组的乘积可以考虑 a[i] 加入前面的 fmax(i-1) 对应的一段,或者单独成为一段,这里两种情况下取最大值。求出所有的 fmax(i) 之后选取最大的一个作为答案。

分析错误与修正

这样做本来看似没有问题,但是如果 a = {5, 6, -3, 4, -3},按照前面的算法可以得到答案为 30,即前两个数的乘积。实际上,更大的乘积是包含全体数字的乘积。问题出在哪里呢?最后一个 -3 所对应的 fmax 的值既不是 -3,也不是 4×(-3),而是 5×6×(-3)×4×(-3)。这说明当前位置的最优解未必是由前一个位置的最优解转移得到的。

正负性的分类讨论

考虑当前位置如果是一个负数的话,我们希望以它前一个位置结尾的某个段的积也是个负数,这样就可以负负得正,并且我们希望这个积尽可能「负得更多」,即尽可能小。如果当前位置是一个正数的话,我们更希望以它前一个位置结尾的某个段的积也是个正数,并且希望它尽可能地大。因此,我们维护一个 fmin(i),它表示以第 i 个元素结尾的乘积最小子数组的乘积,从而得到以下的动态规划转移方程:

fmax(i) = max{fmax(i-1)×a[i], fmin(i-1)×a[i], a[i]}
fmin(i) = min{fmax(i-1)×a[i], fmin(i-1)×a[i], a[i]}

这样,第 i 个元素结尾的乘积最大或最小子数组的乘积可以通过加入第 i-1 个元素结尾的乘积最大或最小的子数组的乘积中,二者加上 a[i],三者取大或小,决定第 i 个元素结尾的乘积最大或最小子数组的乘积。

来源:力扣(LeetCode)

class Solution:
    def maxProduct(self, nums):
        if not nums:
            return 0
        
        maxF = nums[:]
        minF = nums[:]
        for i in range(1, len(nums)):
            maxF[i] = max(maxF[i - 1] * nums[i], nums[i], minF[i - 1] * nums[i])
            minF[i] = min(minF[i - 1] * nums[i], nums[i], maxF[i - 1] * nums[i])
        
        return max(maxF)

标签:结尾,nums,fmax,数组,maxF,DP,乘积
From: https://www.cnblogs.com/peterzh/p/18172952

相关文章

  • DC-2-WordPress-git提权
    靶机概览详情介绍请参考下载地址任务目标:拿下5个flag下载地址:https://www.vulnhub.com/entry/dc-2,311/信息收集nmap信息收集1:使用nmap确定靶机地址是192.168.75.1552:继续使用nmap对靶机做进一步探测,发现靶机开启了80和7744(SSH)端口,先从80端口打开局面3:访问网站,发现URL......
  • DC-6-WordPress-nmap提权
    Vulnhub简介Vulnhub是一个提供了很多漏洞环境的靶场平台,其中的环境基本上都是做好的虚拟机镜像文件,需要使用VMware或者是VirtualBox运行。每个镜像会有破解的目标,大多是Boot2root,从启动虚拟机到获取操作系统的root权限和查看flag。靶场部署这个挑战的最终目标是获得root权限并......
  • c#数组移除同一个值
    数组移除数据,需要循环覆盖的方法。可以快慢双指针。循环一遍。publicintRemoveElement(int[]nums,intval){intn=nums.Length;intlow=0;for(inti=0;i<n;i++){if(nums[i]!=val){nums[low]=nums[......
  • 树状数组(二维偏序)
    题目链接https://leetcode.cn/problems/maximum-sum-queries/description/题目大意题目思路二维偏序问题->一维排序,一维树状数组!题目代码classSolution{public:intsz;vector<int>tr;intlowbit(intx){returnx&-x;}voidupdate(intx,intk)......
  • 05. C语言数组
    数组用于将多个数据集中存储,方便管理,此文将集中存储任何类型数据的语句都称为数组,数组根据存储数据的类型和方式分为同型数组、结构体、共用体、枚举。 【同型数组】同型数组也直接称为数组,用于存储多个类型相同的数据,数组内的数据称为数组元素,数组元素占用连续的虚拟地址,每个......
  • ORA-04063: Package Body “SYS.DBMS_CUBE_EXP” While Expdp
    1.场景数据库版本:11.2.0.4当执行@?/rdbms/admin/awrextr.sql进行awr性能分析数据导出时,报错:ORA-20115:datapumpexportencounterederror:ORA-39127:unexpectederrorfromcalltoexport_string:=SYS.DBMS_CUBE_EXP.INSTANCE_EXTENDED_INFO_EXP('AW$EXPRESS','SYS',......
  • C# String.Split 将字符串按照指定的分隔符分割成一个字符串数组
    以下两种方式都可以分割字符串string[]arr=s.Split('\n');string[]arr=s.Split(newchar[]{'\n'},StringSplitOptions.RemoveEmptyEntries);区别:string[]arr=s.Split('\n');:这种方式使用单个字符作为分隔符,将字符串s按照换行符('\n')进行分割。但是,此......
  • [笔记]树形dp
    树形dp,是一种建立在树形结构上的dp,因此dfs一般是实现它的通用手段。是一种很美的动态规划呢。P1352没有上司的舞会P1352没有上司的舞会。在一棵树中,找到若干个互相独立(即互相没有边直接相连)的点,使它们的权值和最大。我们发现,间隔选择的方法(只选深度为奇数/偶数的点)是不可......
  • #交互,dp#洛谷 7998 [WFOI - 01] 猜数(guess)
    题目传送门分析首先要搞清楚,交互库的自适应会让区间长度尽可能增大(答案自适应)也就是说,如果现在区间为\([l,r]\),你选取的区间为\([l',r']\),那么交互库会让你的区间变成\([l,r'-1]\)和\([l'+1,r]\)中区间更长的那一个,不妨枚举这个长度设\(dp[i]\)表示区间长度为\(i\)......
  • DP Record
    从2024/5/4往后开始记录捏。T1.给你一棵树,定义一个集合的权值为\(\dfrac{\sum_{x\inS}V_x}{\sum_{x\inS}C_x}\)。若一个点\(\inS\),则其父亲也必须\(\inS\)并且\(|S|=k\)。求满足条件的所有集合的最大价值。\(n,k\le2500\)。Solution:注意到那一个奇妙的式子......