zoukankan      html  css  js  c++  java
  • 求和最大的连续子串

    题目: 给定一整型数字a[]={a[0],...,a[n])},找出连续子串{a[x]),a[x+1],...,a[y]},使得和最大,其中,0<=x<=y<=n。

    解法一,用循环来做,扫一遍,用两个变量分别记录当前子序列和、最大的序列和。

    int LongestSubSum(int a[], int n)
    {
        
        int curSum=0, maxSum=-MaxInt, i;
        
        for(i=0; i<n; i++)
        {
            curSum += a[i];     
            
            if(curSum > maxSum)
                maxSum = curSum;
            
            if(curSum < 0)
                curSum = 0;
        }
        
        return maxSum;
    }

    Note:  这种情况能应付输入全部为负数的情况,算法会返回最大的负数
              注意for里面的两个if不能颠倒了,否则全为负数时会返回0,这就不对了

    若要求返回子序列和所在的区间

    void LongestSubSum(int a[], int n, int* start, int* end, int* sum)
    {
        
        int *dp = new int[n];    
        int *begin = new int[n];    
        int i;
        
        if(n>0)
        {
            dp[0] = a[0];
            begin[0] = 0;
        }    
        for(i=1; i<n; i++)        
            if(dp[i-1]+a[i]>a[i])
            {
                dp[i] = dp[i-1] + a[i];
                begin[i] = begin[i-1];
            }        
            else
            {
                dp[i] = a[i];
                begin[i] = i;
            }        
        int idxMax=0;        
        for(i=1; i<n; i++)            
            if(dp[idxMax] < dp[i])    
                idxMax = i;
        *sum = dp[idxMax];
        *start = begin[idxMax];
        *end = idxMax;
    }

    解法二:

    这是典型的dp问题,dp[i]表示以a[i]结尾的连续子串的最大和。(对比错误的:dp[i] 表示a[1..i]的最大连续子串和, 无法递推)

    则递推方程为

    dp[i]= dp[i-1]+a[i]     if  dp[i-1]+a[i] > a[i];
              a[i]                 else

    int LongestSubSum(int a[], int n)
    {
        int *dp = new int[n];
        int i;
        dp[0] = 0;
        for (i=1; i<n; i++)
            if (dp[i-1]+a[i]>a[i])
                dp[i] = dp[i-1] + a[i];
            else
                dp[i] = a[i];
        int max = a[0];
        for (i=1; i<n; i++)
            if (max < dp[i])
                max = dp[i];
        return max;
    }

    若要求返回子序列和所在的区间 

    void LongestSubSum(int a[], int n, int* start, int* end, int* sum)
    {
        int *dp = new int[n];
        int *begin = new int[n];
        int i;
        if(n>0)
        {
            dp[0] = a[0];
            begin[0] = 0;
        }
        for(i=1; i<n; i++)
            if(dp[i-1]+a[i]>a[i])
            {
                dp[i] = dp[i-1] + a[i];
                begin[i] = begin[i-1];
            }
            else
            {
                dp[i] = a[i];
                begin[i] = i;
            }
        int idxMax=0;
        for(i=1; i<n; i++)
            if(dp[idxMax] < dp[i])    
                idxMax = i;
        *sum = dp[idxMax];
        *start = begin[idxMax];
        *end = idxMax;
    }

       

       

      

  • 相关阅读:
    中国SNS用户体验设计分析和互动性浅析
    jQuery的运行机制和设计理念
    Web前端工程师如何给自己定位?
    用户体验这点事儿
    css selection改变文字反选的背景颜色
    HTTP 状态代码
    [翻译]导致网站可用性差的十个最常见问题
    前端开发中的一些用户体验细节
    SQL的行转列问题
    ASP.NET动态添加文本框参考做法
  • 原文地址:https://www.cnblogs.com/xianzhon/p/3739551.html
Copyright © 2011-2022 走看看