1. Maximum sub-segment and 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, the maximum child segment (-,-,-5,-2) is {11,-}, and its sum is 20. (1) The idea for solving the enumeration method 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]} has n names starting with a [1]: {a [1]}, {a [1], a [2]}, {a [1], a [2], a [3]}... {A [1], a [2],... A [n]} has n-1 ...... Start with a [n]: {a [n]} a total of 1 (n + 1) * n/2 consecutive child segments. Use enumeration, the following algorithm should be obtained: the code is as follows: [cpp] // a simple algorithm for the maximum sub-segment of 3d4-1 and the 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; retur N 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 sub-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: [cpp] a simple algorithm to avoid duplication # 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 Start entry of the sum {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 for solving Division and Division: set sequence a [1: n] is divided into two equal segments a [1: n/2] And a [n/2 + 1: n]. The maximum fields and, then, the maximum sub-segments of a [1: n] and the maximum sub-segments of [1], a [1: n] And a [1: n: the maximum sub-segments of n/2] are the same. The maximum sub-segments of [2] and a [1: n] are the same as those of a [n/2 + 1: the maximum sub-segments of n] are the same. The maximum fields of [3] and a [1: n] are the same, 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: [cpp] // The maximum sub-segment of 3d4-1 and the splitting 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 = [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 (su M <rightsum) {sum = rightsum;} return sum;} int MaxSum (int n, int * a) {return MaxSubSum (a, 0, n-1 );} the calculation time T (n) required by the algorithm satisfies the recursive formula: T (n) = O (nlogn ). (3) dynamic programming algorithm to solve the idea of the algorithm is as follows: note, then the maximum sub-segment of the request is: defined by B [j], when B [J-1]> 0, B [j] = B [J-1] + a [j], otherwise B [j] = a [j]. The recursive formula of Dynamic Planning for B [j] is as follows: B [j] = max {B [J-1] + a [j], a [j]}, 1 <= j <= n. The specific code is as follows: [cpp] // dynamic planning algorithm # 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 complexity and space complexity of the preceding algorithm are O (n ). 2. Maximum submatrix and problem (1) Problem description: given an integer matrix A in column n of m rows, 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 in 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 sum of each element is: 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: [cpp] // 3d4-max child matrix sum problem # 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 most Dalian of array The continuation sub-segment 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 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 code can be expressed as follows: 3. Maximum m sub-segment and problem (1) Problem description: given a sequence of a1, a2, a3… consisting 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 largest child segment problem, the recursive formula for calculating B (I, j) is: where, indicating that the I child segment contains a [J-1], the item indicates that the sub-segment I contains only a [j]. Initially, B (0, j) = 0, (1 <= j <= n), B (I, 0) = 0, (1 <= I <= m ). The Code is as follows: [cpp] // maximum MB sub-segment of 3d4-6 # 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 in T [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 child segments, starting from 1, iterate to m and deliver the value of B [I] [j] 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]; // indicates that the last sub-segment only contains 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: [cpp] // maximum m sub-segment of 3d4-7 # 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; // B Array Record the maximum I sub-segment of row I and c [1] = 0; // The c Array records the maximum I-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 the cases can be recursion for (int j = I + 1; j <= I + n-m; j ++) {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 )), the space complexity is O (n ). When m or n-m is a constant, the time complexity and space complexity are O (n ).