152. Maximum Product Subarray 以及 讨论【最大连续子序列】

本文探讨了最大连续子序列问题及其变种——连续最大子段积问题。通过实例讲解了动态规划方法解决这类问题的基本思路,包括状态定义、状态转移方程等,并给出了一段C++代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

152. Maximum Product Subarray 以及 讨论【最大连续子序列】

题目大意:

    连续最大子段积

 

题目思路:

    最大值只能产生在一个正数x一个正数,一个负数乘一个负数,所以维护两个值,一个区间最大值,一个最小值

 

其他的话:

    在讨论这个问题之前,我先来说一说大一刚开学就学了的最简单的dp问题之一的【最大连续子序列】

    先来看一个数组a{ -2, 11, -4, 13, -5, -2 },求连续子序列中和最大的那个

    对于第i个数来说,dp[i]表示,以i结尾的序列最大的和为dp[i]

    状态转移方程为dp[i] = max{ dp[i-1] + a[i], a[i] }

    无论哪个序列和最大,我们都可以表示为以a[i]结尾的子序列

    我们先设dp[0] = a[0]

    那么对于每一个a[i]来说,它只有两个选择

      1)作为上一个序列的结尾

      2)以自己为新的开始,作自己的结尾

    如果那么就比较情况1)和情况2)哪个更大了,所以就出现了上面的表达式max{ dp[i-1] + a[i], a[i] }

    最后只要遍历dp[]就可以找出最大值,因为如第五行所说,最大值一定存在于dp[]之中


同理:

    对于这道题来说,唯一的区别就是前面的负数在这道题的上下文中或许是有用的,而在上一道题里负数是我们所不喜欢的

    又因为xxxxxx....(还没组织好语言。。。。。。。以后再填坑)反正就是最大值可能由一个最大正数乘一个正数得到,也可能由一个最小的负数乘一个负数得到

    我们需要再维护一个dp_min[]来保存以a[i]结尾的最小值

 1 class Solution {
 2 public:
 3     int maxProduct(vector<int>& nums) {
 4         int dp_max[nums.size()];
 5         int dp_min[nums.size()];
 6         dp_max[0] = dp_min[0] = nums[0];
 7         for (int i = 1; i < nums.size(); i++) {
 8             dp_max[i] = max(max(dp_max[i-1]*nums[i], nums[i]), dp_min[i-1]*nums[i]);
 9             dp_min[i] = min(min(dp_min[i-1]*nums[i], nums[i]), dp_max[i-1]*nums[i]);
10         }
11         int ans = dp_max[0];
12         for(int i=1;i<nums.size();i++) ans = max(ans, dp_max[i]);
13         return ans;
14     }
15 };

 

posted @ 2018-01-20 20:38 swallowblank 阅读( ...) 评论( ...) 编辑 收藏
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值