The "sum of maximal continuous sub-sequences" in the evolutionary process of the algorithm

Source: Internet
Author: User

The "sum of maximal continuous sub-sequences" in the evolutionary process of the algorithm

Qiao is clumsy (welcome reprint, but please specify Source: Http://blog.csdn.net/qiaoruozhuo )

Title Description:

Given the sequence of K integers {n1,n2, ..., NK}, any contiguous subsequence can be expressed as {Ni, ni+1, ..., Nj}, where 1 <= i <= J <= K. The maximum contiguous subsequence is the element and the largest of all successive subsequence sequences, such as the given sequence {-2, 11,-4, 13,-5,-2}, with its maximum contiguous subsequence of {11,-4, 13}, and maximum and 20.

Input:

The test input contains several test cases, each of which occupies 2 rows, the 1th line gives the positive integer K (< 10000), the 2nd line gives K integers, and the middle is separated by a space. When k is 0 o'clock, the input ends and the use case is not processed.

Output:

For each test case, output the maximum and in 1 rows. If all k elements are negative, they are defined with a maximum of 0.

Input Example:

6

-2 11-4 13-5-2

10

-10 1 2 3 4-5-23 3 7-21

6

5-8 3 2) 5 0

1

10

3

-1-5-2

3

-1 0-2

0

Output Example:

20

10

10

10

0

0

Algorithm Analysis:

Algorithm 1:

The most immediate idea is the brute force-poor lift. Calculate the possible successive subsequence a[i for each segment: J] and retain the maximum value. Due to the three-layer cycle, the time complexity is O (n^3). The code is as follows:

int maxsubsequencesum_1 (const int a[], int n)//inefficient algorithm 1 {int sum, maxsum, I, j, k;maxsum = 0;fo R (i=0; i<n; i++) {for (j=i; j<n; J + +) {sum = 0;for (k=i; k<=j; k++)//computes continuous subsequence a[i: J] and {sum + = a[k];} if (Sum > maxsum) maxsum = sum;}} return maxsum;} 
<p></p><p></p><p> algorithm 2:</p><p> careful observation of algorithm 1, we found that the most inner loop is not necessary, Because we can set sum = 0 directly in the outermost loop, and then accumulate each a[j] value to get a[i. J] of the sum. The time complexity is O (n^2) because there are only two layers of loops. The code is as follows: </p><p> </p><p>int maxsubsequencesum_2 (const int a[], INTN)//Inefficient algorithm 2</p>< p>{</p><p>       intsum, Maxsum, I, J, k;</p><p>        </p><p>       maxsum= 0;</p><p >       for (i=0; i<n; i++) </p><p>        {</p><p>              sum= 0; </p><p>              for (j=i; j< N J + +) </p><p>              {</p ><p>                     sum+= A[j];</p> <p>                      if (Sum > Maxsum) </p><p>                              maxsum= sum;</p><p>              }</p><p>      }</p><p>        </p><p>       returnmaxsum;</p><p>}</p> <p> </p><p> algorithm 3:</p><p> Although the algorithm 2 reduces the time complexity to O (n^2), but not the efficient algorithm, we can adopt a "divide and conquer" strategy, Dividing the sequence into the left and right two parts, the maximal sub-sequence and may appear in three places: the left half of the second half, or across the middle of the data to occupy the left and the second part. The first two cases can be solved recursively, and the third case needs to calculate the maximum and (must contain the left half of the right element) and the right half of the largest and (must contain the right half of the leftmost element), and then add the two and add together. MostReturns the maximum value of the three. </p><p>       the time complexity can be reduced to O (NLOGN) due to the use of the divide-and-conquer algorithm. The </p><p>       code is as follows: </p><p> </p><p>int Maxsubsequencesum_3 (const int a[], INTN)//Divide </p><p>{</p><p>     conquer algorithm    returnmaxsubsum (A, 0, n-1); </p><p>}</p><p> </p><p>int Maxsubsum (const int a[], int left, intright)//Sub-program of divide-and-conquer algorithm </p><p>{</p><p>        Intmaxleftsum, maxrightsum;</p><p>       Intmaxleftbordersum, maxrightbordersum;</p><p>       IntleftBorderSum, rightbordersum;</p><p>       Intmid, i;</p><p>        </p><p>       if (left = = right) </p><p >              return (A[left] > 0)? A[left]: 0;</p><p>              </p><p>       mid= (left + right)/2;</p><p>        maxleftsum= maxsubsum (A, left, mid); Recursive computation of the left half of the subsequence maximum and </p><p>       maxrightsum= maxsubsum (A, mid+1, right);// Recursive calculation of the right half of the subsequence Max and </p><p>       </p><p>        maxleftbordersum= leftbordersum = 0;</p><p>       for ( I=mid; i>=left; i--)  //The maximum and </p><p>       {</p><p that contain a[mid] subsequence from the middle start to the left >              leftbordersum+= a[i];</p ><p>              if (Leftbordersum > Maxleftbordersum) </p><p>                      maxleftbordersum= leftbordersum;</p><p>      }</p><p>        </p><p>       maxrightbordersum= Rightbordersum = 0;</p><p>       for (i=mid+1; i<=right; i++)    //Calculate the maximum and </p><p>       {</p><p> of a[mid+1] subsequence from the middle to the right               rightbordersum+= a[i];</p> <p>              if (Rightbordersum > Maxrightbordersum) </p><p>                      maxrightbordersum= rightbordersum;</p><p>       }</p><p>       </p><p>        returnmax_3 (Maxleftsum, Maxrightsum, maxleftbordersum+maxrightbordersum); </p><p>} </p><p> </p><p>int max_3 (int A, int b, int c) </p><p>{</p><p>        if (a >= b && a >= c) </p><p>               returna;</p><p>        if (b >= a && b >= c) </p><p>               returnb;</p><p>       if (c >= A & & c >= B) </p><p>              Returnc;</p><p>}</p><p> </p><p> algorithm 4:</p><p> The next step is "dynamic planning." algorithm, which I recommend to everyone, it is the actual complexity of O (N), is the best algorithm to solve such problems. </p><p> dynamic programming is similar to partition method, and its basic idea is to decompose the problem into several sub-problems, solve the problem first, then get the solution of the original problem from the solution of these sub-problems. Different from the partition method, the problem which is suitable for solving with the dynamic programming is not independent of each other by decomposition. If divide-and-conquer method is used to solve this kind of problem, the number of sub-problems is too many, and some sub-problems have been calculated many times. If we can save the answers to the solved sub-problems and find out the answers when we need them, we can avoid a lot of repetitive calculations and save time. We can use a table to record the answers to all the solved sub-problems. Whether or not the sub-problem is used later, as long as it is computed, the results are filled into the table. This is the basic idea of the dynamic programming method. </p><p> in this subject, we can put the maximal subsequence and record of the first I (1<=i<=n) elements, increase I, and finally get the maximal sub-sequence of n elements. In order to document the solution of each sub-problem, we set two arrays: </p><p>intcursum[max];//cursum[i] to store the sum of the maximal contiguous subsequence of a[0..i] that contains a[i] </p><p >intmaxsum[max];//maxsum[i] to store the sum of the largest contiguous subsequence (not necessarily including a[i]) in a[0..i] </p><p> last maxsum[n-1]; Represents the sum of the largest contiguous subsequence in a sequence consisting of n elements. The </p><p> code is as follows: </p><p> </p><p>intmaxsubsequencesum_4 (const int a[], int n)// Dynamic programming algorithm </p><p>{</p><p>   int cursum[max];//cursum[i] is used to store the sum of the maximal contiguous subsequence containing a[i] </p ><p> &nBsp int Maxsum[max];//maxsum[i] to store the sum of the largest contiguous subsequence in a[0..i] (not necessarily including a[i])  </p><p>   int i, max = 0;< /p><p>   </p><p>   maxsum[0] = cursum[0] = a[0];</p><p>    for (i=1; i<n; i++)//storage of the maximum and   </p><p>   {</p><p>   of successive sub-sequences         if (Cursum[i-1] > 0)//If the sum of the preceding successive sub-sequences is greater than 0, add the a[i] up </p><p>                  Cursum[i] = CURSUM[I-1] + a[i];</p><p>          else  // or Start again </p><p>                  Cursum[i] = a[i];</p><p>          </p> <p>          Maxsum[i] = (Cursum[i] >maXsum[i-1])? Cursum[i]: maxsum[i-1];  </p><p>  } </p><p>   if (Maxsum[n-1] > 0 ) </p><p>           max = maxsum[n-1];</p>< p>    </p><p>   return max;</p><p>}</p><p>  The </p><p> algorithm 5:</p><p> algorithm 4 records the solution of each sub-problem by using two arrays. But we notice that this problem only needs to know the value of maxsum[n-1], the previous elements are not necessary, and cursum[i] calculation only depends on Cursum[i-1],maxsum[i] calculation is only dependent on maxsum[i-1], So it is not necessary to record the values of each cursum[i] and Maxsum[i], just record the previous element and iterate over the calculation. </p><p> we can use variable sum and maxsum instead of array cursum[] and maxsum[], and the code is as follows:</p><p> </p><p> int maxsubsequencesum_5 (const int a[], INTN)//dynamic programming algorithm </p><p>{</p><p>   Intsum, Maxsum, i;</p><p>   </p><p>   maxsum= sum = 0;</p><p>    for (i=0; i<n; i++) </p><p>   {</p><p>          sum+= a[i];</p><p>           if (Sum > Maxsum) </p><p>                  maxsum= sum;</p><p>           elseif (Sum < 0)//continuous sub-sequence with less than 0, then restart </p><p>                  sum= 0;</p><p>  } </p><p>   </p><p>   returnmaxsum;</p><p>}</p><p > </p><p> If you can understand the algorithm above, you can accept further challenges and try the following questions. </p><p> Topic Description:</p><p> Now I think you've got an AC in Ignatius Lee's "biggest and" problem. As a brave acmer, we always challenge ourselves to more difficult problems, and now you are facing a more difficult problem. </p><p>  given a sequence of sequential integers S1, S2, S3, S4 ... Sx... Sn (1≤x≤n≤1,000,000,-32768≤sx≤32767). We define a function sum (i, j) = si+ ... + Sj (1≤i≤j≤n) .</p><p> now gives an integer m (M > 0), your task is to find M to I and J, making sum (I1, J1) +sum (I2, J2) + sum (i3, J3) + ... + sum (IM, JM) max , where IX≤IY≤JX or IX≤JY≤JX is not allowed to occur. </p><p> but I'm lazy and I don't want to write a special judgment module, so you don't need to output m to I and J, and just output the maximum value of sum (ix, JX) (1≤x≤m). </p><p> </p><p> input:</p><p> Each test case will start with two integers m and n, followed by n integers S1, S2, S3 ... Sn. Until the end of the read-in file. </p><p> </p><p> output:</p><p> The maximum value that is stated in the title description on a single line. </p><p> </p><p> Input Example: </p><p>1 3 1 2 3</p><p>2 6-1 4-2 3-2 3</p& Gt;<p> </p><p> Output Example:</p><p>6</p><p>8</p><p>  </p><p> algorithm analysis: </p><p> algorithm 6:</p><p>       This is a typical application of dynamic programming algorithms, we can imitate the solution of the previous algorithm 4, using a two-dimensional array Maxsum[max][max] to store all the total J elements into the group I obtained the largest continuous sub-sequence of the sum, wherein 1<=j<=n,1<=i< =m. When the max value is large, we'd better set the two-dimensional array Maxsum[max][max] to a global variable, otherwise the stack space will not be allocated correctly. </p><p>     &nbsp The code is as follows: </p><p> </p><p>int maxsubplus (const int a[], int m, INTN)// Dynamic planning records divide the total J elements into the sum of the maximal contiguous subsequence obtained by the group I </p><p>{</p><p>       Intmaxsum[max][max] = {0};</p><p>    Intcursum[max] = {0};//cursum[i] used to store contains a[i] The sum of the maximal continuous subsequence of </p><p>   int I, j;</p><p> </p><p>    for (i=1; i<=m; i++)//dynamic planning, scale from small to large, with Maxsum[i][j] Records of the total J elements into the group I obtained the sum of the largest continuous sub-sequence </p><p>     {</p><p>       maxsum[i][i] = cursum[i] = maxSum[i-1][i-1] + A[ i];//if the I element is divided into groups of I, then each element should be used </p><p>       {</p><p>            for (j=i+1; j<=n; j + +) </p><p>            {</p><p>                 if (Cursum[j-1] >maxsum[i-1][j-1])//curSum[j] storage contains a[j] Sum of the maximal continuous sub-sequences of group I   </p><p>                     Cursum[j] = cursum[j-1] +a[j];</p><p>                 else</p><p>                     Cursum[j ] =maxsum[i-1][j-1] + a[j];</p><p>                 </p><p>                 Maxsum[i][j] = (Cursum[j] >maxsum[i][j-1])? CURSUM[J]: maxsum[i][j-1];</p><p>            }</p><p>       } </p><p>   }</p><p> </p><p>    return maxsum[m][n];</p><p>}</p><p> </p><p> Algorithm 7:</p><p >       when the max value is small, algorithm 6 is feasible, but due to the max= in the subject 1000001, it's really too big (the only way to allocate this large array space is to set all the arrays as global variables). So it is necessary to imitate the Fibonacci sequence, do not need to record all the f[i] values, just iterate records f[i-1] and f[i-2] can be obtained f[i] method (the algorithm 5 on the algorithm 4 optimization is also adopted this method), set the following 3 arrays to iterate records intermediate results: </p ><p>int cursum[max];//is used to store the sum </p><p>int of the largest contiguous subsequence containing a[j] presum[max];// Used to store the sum of the largest contiguous subsequence that is obtained by dividing a total of j elements into a i-1 group </p><p>int maxsum[max];//is used to store the sum of the largest contiguous sub-sequences obtained by dividing a total of j elements into groups of I. The basic idea of the </p><p>    algorithm is that I and J respectively as outer, inner loop variables, both are small to large, with MAXSUM[J] record the total J elements are divided into the sum of the maximal continuous sub-sequences obtained by group I. If I are divided into groups I, then each element will be used, at this time maxsum[i] =cursum[i] = presum[i-1] + a[i];</p><p>    and then continue to add new elements, That is, increase the value of J, calculate whether the addition of new elements will be able to obtain a larger continuous sub-sequence and. Compare Cursum[j-1] and presum[j-1] to sum the larger and new elements a[j] to see if the new and larger than maxsum[j-1], and store the maximum value currently obtained in Maxsum[j. </p><p>  The key to the     algorithm is to copy the maxsum[] value to presum[] at the end of each round to allow for the next iteration of the calculation. The code is as follows:</p><p> </p><p> #include <stdio.h>  </p><p> #include < stdlib.h>  </p><p>  </p><p> #define MAX 1000001  </p><p>  </p><p>int a[max]; </p><p>int cursum[max];//used to store the sum    </p of the largest contiguous subsequence containing a[j] The ><p>int presum[max];//is used to store the sum   </p><p>int of the largest contiguous subsequence obtained by dividing a total of j elements into i-1 groups maxsum[max];// Used to store the sum   </p><p>  </p><p>int maxsubplus (const int a[], int m, of the largest contiguous subsequence obtained by dividing a total of J elements into Group I, INTN);//dynamic planning records divide a total of J elements into the sum of the largest contiguous subsequence of the group I   </p><p>  </p><p>int main (void)   < /p><p>{  </p><p>   int I, M, n;  </p><p>      </p><p>   while (scanf ("%d%d", &m,&n)!=EOF)   </p> <p>   {  &LT;/P&GT;<p>       for (I=1; i<=n;i++)   </p><p>   &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;SCANF ("%d", &a[i]); </p><p>        printf ("%d\n", Maxsubplus (A, M, N));  </p><p>    }  </p><p>  </p><p>   return 0;  </p><p>}   </p><p>  </p><p>//similar to Fibonacci sequence, do not need to record all F[i] values, just iterate records f[i-1] and f[i-2] can be obtained f[i]    </p><p>int maxsubplus (const int a[], int m, INTN)//Dynamic planning records the sum of the largest contiguous sub-sequences obtained by dividing a total of n elements into M-groups   </p> <p>{  </p><p>   int I, j;  </p><p>      </p><p>    for (j=0; j<=n; j + +)//Initialize   </p><p>  &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;PRESUM[J] = 0;  </p><p>   for (i=1; i&lT;=m; i++)///dynamic planning, scale from small to large, with MAXSUM[J] record the total J elements into the sum of the largest continuous sub-sequences obtained by group I    </p><p>   {  </p><p>       maxsum[i] = Cursum[i] = preSum[i-1] + a[i];//If I are divided into groups of I , each element must be used on   </p><p>       for (j=i+1; j<=n; j + +)   </ p><p>       {  </p><p>            if (Cursum[j-1] > Presum[j-1])//cursum[j] stores the sum of the maximal contiguous subsequence of group I containing a[j]      </p><p>                 Cursum[j] = cursum[j-1] +a[j];  </p><p>            else  </p><p>                 Cursum[j] = presum[j-1] +a[j];  </p><p>              </p><p>                 Maxsum[j] = (Cursum[j] >maxsum[j-1])? CURSUM[J]: maxsum[j-1];  </p><p>       }  </p>< P>       for (j=i; j<=n; j + +)//copy maxsum[] value to presum[] for next iteration calculation     &LT;/P&GT;&LT;P&GT;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;PRESUM[J] = MaxSum[j] ;  </p><p>   }  </p><p>  </p><p>    return maxsum[n];  </p><p>}  </p><p> </p><p> here, The correlation algorithm of the sum of the maximal continuous sub-sequence is introduced, the dynamic planning strategy is an efficient and practical strategy, the code implementation is very simple, but it is difficult to understand, I will be in the next series of articles on the dynamic planning of the understanding of the record down, and everyone to share, thank you for your attention. </p>

The sum of the maximal contiguous subsequence of the evolutionary process of the algorithm

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.