zoukankan      html  css  js  c++  java
  • 动态规划:最大连续子序列乘积

    题目描写叙述:

    给定一个浮点数序列(可能有正数、0和负数),求出一个最大的连续子序列乘积。

    分析:若暴力求解,须要O(n^3)时间,太低效,故使用动态规划。
    data[i]:第i个数据,dp[i]:以第i个数结尾的连续子序列最大乘积,
    若题目要求的是最大连续子序列和,则易确定状态转移方程为:
    dp[i]=max(data[i],dp[i-1]+data[i])(dp[i]为以第i个数结尾的连续子序列最大和)

    但乘积存在负负得正的问题,即原本非常小的负数成了一个负数反而变大了。(负数逆袭了),

    故不能照抄加法的转移方程,为了解决问题。须要定义两个数组:

    dp1[i]:以第i个数结尾的连续子序列最大乘积
    dp2[i]:以第i个数结尾的连续子序列最小乘积
    转移方程:
    dp1[i]=max(data[i],dp1[i-1]*data[i],dp2[i-1]*data[i]);

    dp2[i]=min(data[i],dp1[i-1]*data[i],dp2[i-1]*data[i]);

    最后遍历dp1得到最大值即为答案。


    代码例如以下:

    #include<stdio.h>
    double max(double a,double b){return a>b?a:b;}
    double min(double a,double b){return a<b?a:b;}
    double dp1[100001];
    double dp2[100001];
    double data[100001];
    double helper(double data[],int n)
    {
      dp1[0]=data[0];
      dp2[0]=data[0];
      for(int i=1;i<n;i++)
      {
    	  dp1[i]=max(data[i],max(dp1[i-1]*data[i],dp2[i-1]*data[i]));
    	  dp2[i]=min(data[i],min(dp1[i-1]*data[i],dp2[i-1]*data[i]));
      }
      double ans=dp1[0];
      for(int i=1;i<n;i++)
      {
    	  ans=max(ans,dp1[i]);
      }
      return ans;
    }
    
     
    int main(void)
    {
        int i,n;
        while(scanf("%d",&n)!=EOF)
        {
            for(i=0; i<n; ++i)
            {
                scanf("%lf", &data[i]);
            }
            double ans = helper(data, n);
            printf("%lf
    ",ans);
        }
        return 0;
    }
    事实上还能够对空间复杂度进行化简,代码例如以下:

    double helper(double data[], int n)
    {
        double ans = data[0];
        double localMax = data[0];
        double localMin = data[0];
        for(int i=1; i<n; ++i)
        {
            double t1 = max(data[i], max(localMax*data[i], localMin*data[i]) );
            double t2 = min(data[i], min(localMax*data[i], localMin*data[i]) );
     
            localMax = t1;
            localMin = t2;
     
            ans = localMax > ans ?

    localMax : ans; } return ans; }




  • 相关阅读:
    python 连接操作mysql数据库
    (转)postfix疯狂外发垃圾邮件之分析与解决
    ansible 常用方法
    用python2.7.9 写个小程序搜索某个目录下行有某关键字
    python获取文件扩展名的方法(转)
    ceph 池管理
    UVALive 5412 Street Directions
    UVALive 3231 Fair Share
    UVA 11478 Halum
    2015 Multi-University Training Contest 4 hdu 5338 ZZX and Permutations
  • 原文地址:https://www.cnblogs.com/yxysuanfa/p/7156462.html
Copyright © 2011-2022 走看看