zoukankan      html  css  js  c++  java
  • 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 };
  • 相关阅读:
    帧同步资料收集
    随机数种子问题
    【转】 DOTA2中的伪随机及其lua实现
    C++ 异常机制分析
    细说new与malloc的10点区别
    static关键字总结
    C++11 并发编程基础(一):并发、并行与C++多线程
    论一个程序员的自我修养
    gSoap的多线程程序
    面试常见问题:
  • 原文地址:https://www.cnblogs.com/liwenchi/p/8321859.html
Copyright © 2011-2022 走看看