Maximum sub-segments and problems, maximum sub-matrix and problems, maximum M sub-segments and Problems

Source: Internet
Author: User

1. Maximum child segments and Problems

Problem definition:For the given sequence A1, A2, A3 ...... An. Find a continuous sub-segment of the sub-segment to maximize the sum. For example (
-,-,-5,-2) the maximum child segment is {11,-} and its sum is 20.

(1) Enumeration Method

The concept of enumeration is as follows:

Start with a [0]: {A [0]}, {A [0], a [1]}, {A [0], a [1], A [2]}... {A [0], a [1],... A [n]} n in total

Start with a [1]: {A [1]}, {A [1], a [2]}, {A [1], a [2], A [3]}…… {A [1], a [2],... A [n]} n-1 in total

......

Start with a [n]: {A [n]} 1 in total

A total of (n + 1) * n/2 consecutive sub-segments. Use enumeration to obtain the following algorithm:
The Code is as follows:

// 3d4-1 SIMPLE algorithm for maximum sub-segment and problem # include "stdafx. H "# include <iostream> using namespace STD; int maxsum (int n, int * a, Int & besti, Int & bestj); int main () {int A [] = {-,-,-5,-2}; For (INT I = 0; I <6; I ++) {cout <A [I] <";}int besti, bestj; cout <Endl; cout <" the maximum continuous sub-segment of array a is: A ["<besti <": "<bestj <"]: "<maxsum (6, A, besti, bestj) <Endl; return 0 ;} int maxsum (int n, int * a, Int & besti, Int & bestj) {int sum = 0; For (INT I = 0; I <n; I ++) // control the sum Start entry {for (Int J = I; j <n; j ++) // control the sum end entry {int thissum = 0; for (int K = I; k <= J; k ++) // sum {thissum + = A [k];} If (thissum> sum) // calculate the maximum child segment and {sum = thissum; besti = I; bestj = J ;}} return sum ;}

From the three for loops of this algorithm, we can see that it requires O (N ^ 3) computing time ). In fact, if you notice that the last for loop in the algorithm can be omitted to avoid repeated computation, so that the algorithm can be improved. The improved code is as follows:

// 3d4-2 SIMPLE algorithm that avoids duplication of maximum sub-segments and problems # include "stdafx. H "# include <iostream> using namespace STD; int maxsum (int n, int * a, Int & besti, Int & bestj); int main () {int A [] = {-,-,-5,-2}; For (INT I = 0; I <6; I ++) {cout <A [I] <";}int besti, bestj; cout <Endl; cout <" the maximum continuous sub-segment of array a is: A ["<besti <": "<bestj <"]: "<maxsum (6, A, besti, bestj) <Endl; return 0 ;} int maxsum (int n, int * a, Int & besti, Int & bestj) {int sum = 0; For (INT I = 0; I <n; I ++) // control the sum Start entry {int thissum = 0; For (Int J = I; j <= N; j ++) // control the sum end item {thissum + = A [J]; // sum if (thissum> sum) {sum = thissum; besti = I; bestj = J ;}}} return sum ;}

(2) method of division and Control

The principle of division and control is as follows:

Divide sequence a [1: N] into two equal segments A [1: n/2] And a [n/2 + 1: N], find the maximum fields and values of the two segments respectively, then the maximum sub-segments of a [1: N] and the three cases:

The maximum sub-segments of [1] and a [1: N] are the same as the maximum sub-segments of a [1: n/2;

The maximum sub-segments of [2] and a [1: N] are the same as the maximum sub-segments of a [n/2 + 1: N;

The maximum field of [3] and a [1: N] is the sum, and 1 <= I <= n/2, n/2 + 1 <= j <= n.

Use a recursive method to obtain the scenario [1], [2]. For the scenario [3], we can see that a [n/2] And a [n/2 + 1] are in the optimal subsequence. Therefore, it can be calculated in a [1: n/2] and calculated in a [n/2 + 1: N. Then S1 + S2 is the optimal value when [3] occurs.

The Code is as follows:

// The largest sub-segment of 3d4-1 and the problematic Sub-division algorithm # include "stdafx. H "# include <iostream> using namespace STD; int maxsubsum (int * a, int left, int right); int maxsum (int n, int * A); int main () {int A [] = {-,-,-5,-2}; For (INT I = 0; I <6; I ++) {cout <A [I] <";}cout <Endl; cout <" the maximum continuous sub-segment of array a is: "<maxsum (6, a) <Endl; return 0;} int maxsubsum (int * a, int left, int right) {int sum = 0; If (Left = right) {sum = A [left]> 0? A [left]: 0;} else {int center = (left + right)/2; int leftsum = maxsubsum (A, left, center); int rightsum = maxsubsum (, center + 1, right); int S1 = 0; int lefts = 0; For (INT I = center; I> = left; I --) {lefts + = A [I]; If (lefts> S1) {S1 = lefts;} int S2 = 0; int rights = 0; for (INT I = center + 1; I <= right; I ++) {rights + = A [I]; If (rights> S2) {S2 = rights ;}} sum = S1 + S2; If (sum <leftsum) {sum = leftsum;} If (sum <rightsum) {sum = rightsum ;}} return sum ;} int maxsum (int n, int * A) {return maxsubsum (A, 0, n-1 );}

The computing time t (n) required by the algorithm meets the following recursive formula:

The recursive equation T (n) = O (nlogn ).

(3) dynamic planning algorithm solution

The algorithm logic is as follows:

Note, the maximum child segment is:

According to the definition of B [J], when B [J-1]> 0, B [J] = B [J-1] + A [J], otherwise, B [J] = A [J]. The Dynamic Planning recursive formula of B [J] is as follows:

B [J] = max {B [J-1] + A [J], a [J]}, 1 <= j <= n.

The Code is as follows:

// Dynamic Planning Algorithm for maximum sub-segments and problems of 3d4-1 # include "stdafx. H "# include <iostream> using namespace STD; int maxsum (int n, int * A); int main () {int A [] =, -5,-2}; For (INT I = 0; I <6; I ++) {cout <A [I] <"";} cout <Endl; cout <"the maximum continuous sub-segment of array a is:" <maxsum (6, a) <Endl; return 0 ;} int maxsum (int n, int * A) {int sum = 0, B = 0; For (INT I = 1; I <= N; I ++) {If (B> 0) {B + = A [I];} else {B = A [I];} If (B> sum) {sum = B ;}} return sum ;}

The time and space complexity of the preceding algorithms are O (n ).

2. Maximum submatrix and Problems
(1) Problem description: given an integer matrix A in n columns of m rows, we try to find a submatrix of A. The sum of the elements in the period is the largest.

(2) Problem Analysis:

Use a two-dimensional array a [1: m] [1: N] to represent the integer matrix of n columns of the given m row. The child array a [I1: I2] [J1: J2] indicates the child matrix with the column coordinates (I1, J1) and (I2, J2) in the upper left and lower right corner, the elements are as follows:

The optimal value of the maximum submatrix problem is. If you use the direct Enumeration Method to Solve the maximum submatrix and problem, it takes O (M ^ 2n ^ 2) time. Note that, in formula, set, then

It is easy to see that this is the largest sub-segment and problem in one-dimensional situations. Therefore, with the help of maxsum, the maximum child matrix and the dynamic planning algorithm of the problem can be designed as follows:

 

// Questions about the sum of 3d4-5 largest submatrices # include "stdafx. H "# include <iostream> using namespace STD; const int M = 4; const int n = 3; int maxsum (int n, int * A); int maxsum2 (INT m, int N, int A [m] [N]); int main () {int A [] [N] = {4, 8 },{-6, 7, 6 },{ 0, 9,-5 }}; for (INT I = 0; I <m; I ++) {for (Int J = 0; j <n; j ++) {cout <A [I] [J] <";}cout <Endl ;} cout <Endl; cout <"the maximum continuous sub-segment of array a is:" <maxsum2 (m, n, a) <Endl; return 0 ;} int maxsum2 (int m, int N, int A [m] [N]) {int sum = 0; int * B = new int [n + 1]; for (INT I = 0; I <m; I ++) // hold {for (int K = 0; k <n; k ++) {B [k] = 0 ;}for (Int J = I; j <m; j ++) // enumerate the initial row I, end row J {for (int K = 0; k <n; k ++) {B [k] + = A [J] [k]; // B [k] is the sum of the vertical columns int max = maxsum (n, B); If (max> sum) {sum = max ;}}} return sum ;} int maxsum (int n, int * A) {int sum = 0, B = 0; For (INT I = 1; I <= N; I ++) {If (B> 0) {B + = A [I];} else {B = A [I];} If (B> sum) {sum = B ;}} return sum ;}

The execution process of the maxsum2 method can be expressed as follows:


3. Maximum M sub-segments and Problems

(1) Problem description: Given the sequence A1, A2, A3… composed of N integers (which may be negative ...... An, and a positive integer m, it is required to determine that the sum of m non-Intersecting child segments of this sequence reaches the maximum. The maximum sub-segment and the problem are the maximum M field and the special case when M = 1.

(2) Problem Analysis: Set B (I, j) to represent the maximum value of the I sub-segment and in the first J items of array, and the sub-segment I contains a [J] (1 <= I <= m, I <= j <= N), the optimal value is obviously. Similar to the maximum child segment problem, the recursive formula for calculating B (I, j) is:

Where, indicates that the I child segment contains a [J-1], and the item indicates that the I child segment contains only a [J]. Initially, B (0, j) = 0, (1 <= j <= N), B (I, 0) = 0, (1 <= I <= m ).

The Code is as follows:

// 3d4-6 maximum M sub-segment problem # include "stdafx. H "# include <iostream> using namespace STD; int maxsum (int m, int N, int * A); int main () {int A [] = {0, 2, 3, -7,6, 4,-5}; // The array script starts from 1 for (INT I = 1; I <= 6; I ++) {cout <A [I] <";}cout <Endl; cout <" the maximum continuous sub-segment of array a is: "<maxsum, a) <Endl;} int maxsum (int m, int N, int * A) {If (n <M | M <1) return 0; int ** B = new int * [M + 1]; for (INT I = 0; I <= m; I ++) {B [I] = new int [n + 1] ;}for (INT I = 0; I <= m; I ++) {B [I] [0] = 0 ;}for (Int J = 1; j <= N; j ++) {B [0] [J] = 0 ;} // enumerate the number of sub-segments, starting from 1 and iteration to M. The for (INT I = 1; I <= m; I ++) {// n-M + I limit to avoid redundant operations. When I = m, the maximum value of J is N. Based on this, all the cases for (Int J = I; j <= N-M + I; j ++) {If (j> I) {B [I] [J] = B [I] [J-1] + A [J]; // stands for a [J] together with a [J-1, all in the last child segment for (int K = I-1; k <j; k ++) {If (B [I] [J] <B [I-1] [k] + A [J]) B [I] [J] = B [I-1] [k] + A [J]; // represents that the last child segment contains only a [J]} else {B [I] [J] = B [I-1] [J-1] + A [J]; // when I = J, each item is a sub-segment }}int sum = 0; For (Int J = m; j <= N; j ++) {If (sum <B [m] [J]) {sum = B [m] [J] ;}} return sum ;}

The time complexity of the preceding algorithm is O (Mn ^ 2), and the space complexity is O (Mn ). In fact, in the above algorithm, when B [I] [J] is calculated, only the values of the I-1 and I rows of array B are used. Therefore, the algorithm does not need to store the entire array as long as it stores the current row of array B. On the other hand, the value can be pre-calculated and saved when the I-1 row is computed. When calculating the value of row I, you do not have to recalculate the value, saving the computing time and space. Therefore, the algorithm can be further improved as follows:

// 3d4-7 maximum M sub-segment problem # include "stdafx. H "# include <iostream> using namespace STD; int maxsum (int m, int N, int * A); int main () {int A [] = {0, 2, 3, -7,6, 4,-5}; // The array script starts from 1 for (INT I = 1; I <= 6; I ++) {cout <A [I] <";}cout <Endl; cout <" the maximum continuous sub-segment of array a is: "<maxsum, a) <Endl;} int maxsum (int m, int N, int * A) {If (n <M | M <1) return 0; int * B = new int [n + 1]; int * c = new int [n + 1]; B [0] = 0; // array B records the maximum I sub-segment of row I and C [1] = 0; // array C records the maximum I-of row I-1- 1 sub-segment and for (INT I = 1; I <= m; I ++) {B [I] = B [I-1] + A [I]; c [I-1] = B [I]; int max = B [I]; // n-M + I limit to avoid extra operations when I = m, the maximum value of J is N. According to this, all cases for (Int J = I + 1; j <= I + N-m; j ++) can be recursion) {B [J] = B [J-1]> C [J-1]? B [J-1] + A [J]: C [J-1] + A [J]; C [J-1] = max; // pre-Save the maximum J-1 sub-segment and if (max <B [J]) {max = B [J];} c [I + N-M] = max;} int sum = 0; For (Int J = m; j <= N; j ++) {If (sum <B [J]) {sum = B [J] ;}} return sum ;}

The time complexity of the preceding algorithm is O (M (n-M), and the space complexity is O (n ). When M or N-M is a constant, the time complexity and space complexity are O (n ).

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.