dp related problems (update continuously)

Leetcode Maximum Product Subarray

这道题是说给一个整数数组,求最大的连续子数组的乘积。纠结了好久数组中包含0和负数怎么处理,其实关键就是负数的处理,于是我们记一个最大正值和最小负值,这样就可以很容易的处理负数的情况了。对于当前元素如果是负数,那么最大值可能是前面的最小负值乘以当前的负数;如果是正数,那么则很有可能是前面的最大正值乘以当前正数。

于是我们记dpp[i]为以第i个数结尾的最大正值,dpn[i]表示以第i个数结尾的最小负值,那么就有下面的两种更新情况:

if A[i] > 0:

dpp[i] = max(A[i], dpp[i-1]*A[i])

dpn[i] = min(0, dpn[i-1]*A[i])

if A[i] < 0:

dpn[i] = min(A[i], A[i]*dpp[i-1])

dpp[i] = max(0, A[i]*dpn[i-1])

并且在遍历的过程中用dpp[i]更新最终的结果值就行了,具体可参考下面的代码。

class Solution:
    # @param A, a list of integers
    # @return an integer
    def maxProduct(self, A):
        if A == None:
            return 0
        if len(A) == 0:
            return 0
        if len(A) == 1:
            return A[0]

        dpp = [0]*len(A)
        dpn = [0]*len(A)

        ans = A[0]
        if A[0] > 0 :
            dpp[0] = A[0]
        elif A[0] < 0 :
            dpn[0] = A[0]

        for i in range(1, len(A)):
            if A[i] == 0 :
                continue
            elif A[i] > 0 :
                dpp[i] = max(A[i], A[i]*dpp[i-1])
                dpn[i] = min(0, A[i]*dpn[i-1])
            else:
                dpn[i] = min(A[i], A[i]*dpp[i-1])
                dpp[i] = max(0, A[i]*dpn[i-1])
            ans = max(dpp[i], ans)
        return ans
        
时间: 2024-10-29 19:10:09

dp related problems (update continuously)的相关文章

leetcode tree related problems (update continuously)

leetcode Binary Tree Level Order Traversal 这道题是要进行二叉树的层次遍历,对于层次遍历,最简单直观的办法就是进行BFS.于是我们只需要维护一个队列就可以了,队列里面的元素需要记录该节点的内容和节点所在的层,依次从队列中取出节点进行扩展就可以了. # Definition for a binary tree node # class TreeNode: # def __init__(self, x): # self.val = x # self.left

C++ 编程技巧积累 (Update Continuously)

最近写C++或者Python的过程中发现,好多函数的调用形式总是记不清楚,需要搜索或者查官方文档.于是乎希望能进一步熟悉这些函数的使用,这里先一点点的记录C++一些函数的使用,一边以后过来查阅. 1. 如何拼接两个vector 在C++中很多功能不像Python中那么方便,比如说要拼接两个vector,在C++中就需要自己实现.但是vector有一个非常好的函数可以简便的实现该功能,那就是insert函数.查看文档可以知道,该函数有多重重载形式,其中一个就是 void insert (itera

hdu 4521 小明系列问题——小明序列(线段树+DP或扩展成经典的LIS)

小明系列问题--小明序列 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Total Submission(s): 1553    Accepted Submission(s): 457 Problem Description 大家都知道小明最喜欢研究跟序列有关的问题了,但是也就由于这样,小明差点儿已经玩遍各种序列问题了.可怜的小明苦苦地在各大站点上寻找着新的序列问题,但是找来

hdu 5311 Hidden String dp o(n)算法 深搜

Hidden String Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 857    Accepted Submission(s): 322 Problem Description Today is the 1st anniversary of BestCoder. Soda, the contest manager, gets

POJ1717 Dominoes DP,背包的变形

这道题目比较短,而且有图片很容易懂题意,就是每一张牌,分为上下两部分,上面有几个点,代表上部分为几,下面同样,然后n张牌平行竖直放置,这样每一张牌的上面部分组成第一行,下面部分组成第二行,上下两行的和是有差异的值为gap,每一张牌可以上下反一下,这样可以是的差异值gap缩小,问你使得gap值最小 需要翻牌的最少次数 首先这道题目跟POJ1837有点类似,但是 边界设置这道题明显会麻烦许多,因为之前做过了POJ1837,所以这道题一上来就选择了那个方法,但是a,b值的差异极端为6000,又有负的,

hdu4521(线段树+dp)

传送门:小明系列问题——小明序列 题意:有n个数,求间距大于d的最长上升序列. 分析:dp[i]表示在i点以a[i]结束距离大于d的最长上升序列,然后每更新到第i点时,取i-d之前小于a[i]的数为结束的最长上升序列进行状态转移,并维护前i-d之前的最大上升序列,维护i-d之前的每点为结束的最长上升序列用线段树维护即可. #pragma comment(linker,"/STACK:1024000000,1024000000") #include <cstdio> #inc

hdu6078 Wavel Sequence dp+二维树状数组

//#pragma comment(linker, "/STACK:102400000,102400000") /** 题目:hdu6078 Wavel Sequence 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6078 题意:给定a序列和b序列.从a中取一个子序列x(数的位置顺序保持不变),子序列每个数满足a1<a2>a3<a4>a5<a6... 波浪形 从b中取相同长度的子序列y,也满足波浪形. 如果x

codeforces#426(div1) B - The Bakery (线段树 + dp)

题意:把 n 个数划分成 m 段,要求每组数不相等的数的数量最大之和. 思路: dp方程 : dp[i][j] = max( dp[k][j-1] + v(k, i) );( j<=k<i , k = j, j+1, +...+ i-1) dp[i][j]表示第 i 个数分到第 j 段的最大值. v(k, i) 表示k~i中不同数的个数,此处用hash记录每个数上一次出现的位置,从上一次出现的位置到当前位置的 dp[i][j-1] 值均可+1. 此时时间复杂度 O(n*m*log(n)). 线

hdu 2227 树状数组+dp

题意是求一个数列的不递减的子序列的个数: 很显然,如果只用dp来做的话时间是O(n*n) 因为dp[i]为前i个数可能的方案,则状态转移方程为dp[i]=sum(dp[j],j<i&&num[j]<=num[i])+1 对小数据坑定能过 但大数据就超时了,这里用到了树状数组来优化: 先对num按数来进行排序,(这道题因为数据较大  用到了离散化) 因为更新是是按原序更新的,及i之前的num[j]一定比num[i]小,维护了不递减的原则,更新是从mark[i](表示原序列i在排序