Classic question one: maximal contiguous sub-segments and problems
Borrowed from the original Wind Zhong da Nyingchi: http://blog.csdn.net/liufeng_king/article/details/8632430
(See for yourself, copy it is OK ~ ~ ~)
Problem: Give a number, false with N, there is a negative, you want to find the largest continuous field and. For example: ( -2,11,-4,13,-5,-2) The maximum child segment is {11,-4,13} and is 20.
The method of enumeration of idiots (N^3) is not said.
Here are two main approaches:
(1) Solving by divide-and-conquer method
The idea of splitting and administering the law is as follows:
Divide the sequence a[1:n] into equal lengths of two segments A[1:N/2] and a[n/2+1:n], respectively, to find the maximum field of the two paragraphs and, then a[1:n] the maximum sub-segment and three cases:
[1], A[1:n] The largest sub-segment and the largest sub-segment and the same as A[1:N/2];
[2], A[1:n] The largest sub-segment and the largest sub-segment and the same as a[n/2+1:n];
[3], a[1:n] the maximum field and is, and 1<=i<=n/2,n/2+1<=j<=n.
The case can be obtained by recursive method [1],[2]. For the case [3], it can be seen A[N/2] and a[n/2+1] in the optimal sub-sequence. So it can be calculated in A[1:N/2] and calculated in a[n/2+1:n]. The S1+S2 is the optimal value when the case [3] occurs.
The specific code is as follows:
//a divide-and-conquer algorithm for 3d4-1 maximal sub-segments and problems#include"stdafx.h"#include<iostream>using namespacestd;intMaxsubsum (int*a,intLeftintRight );intMaxsum (intNint*a);intMain () {intA[] = {-2, One,-4, -,-5,-2}; for(intI=0; i<6; i++) {cout<<a[i]<<" "; } cout<<Endl; cout<<"the maximum contiguous sub-segments of array A are:"<<maxsum (6, a) <<Endl; return 0;}intMaxsubsum (int*a,intLeftintRight ) { intsum =0; if(left = =Right ) {Sum= a[left]>0? A[left]:0; } Else { intCenter = (left+right)/2; intLeftsum =maxsubsum (A,left,center); intRightsum = Maxsubsum (a,center+1, right); intS1 =0; intLefts =0; for(intI=center; i>=left;i--) {lefts+=A[i]; if(lefts>S1) {S1=lefts; } } intS2 =0; intRights =0; for(inti=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; } } returnsum;}intMaxsum (intNint*a) { returnMaxsubsum (A,0, N-1);}
The calculation time required by the algorithm T (n) satisfies the recursive formula:
To solve this recursive equation, it is known that T (n) =o (NLOGN).
(2) Dynamic Programming algorithm Solution
The algorithm ideas are as follows:
The maximum number of sub-segments to be asked is:
Known by B[j], when B[j-1]>0, B[j]=b[j-1]+a[j], otherwise b[j]=a[j]. The B[J] Dynamic programming recursion is as follows:
B[j]=max{b[j-1]+a[j],a[j]},1<=j<=n.
The specific code is as follows:
//dynamic programming algorithm for 3d4-1 maximal sub-segments and problems#include"stdafx.h"#include<iostream>using namespacestd;intMaxsum (intNint*a);intMain () {intA[] = {-2, One,-4, -,-5,-2}; for(intI=0; i<6; i++) {cout<<a[i]<<" "; } cout<<Endl; cout<<"the maximum contiguous sub-segments of array A are:"<<maxsum (6, a) <<Endl; return 0;}intMaxsum (intNint*a) { intsum=0, b=0; for(intI=1; i<=n; i++) { if(b>0) {b+=A[i]; } Else{b=A[i]; } if(b>sum) {Sum=b; } } returnsum;}
Classic question two: Maximal sub-matrices and problems
(1) Problem description: Given an M row n column of the integer matrix A, try to find a sub-matrix, the sum of the elements of the period is the largest.
(2) Problem analysis:
A two-dimensional array a[1:m][1:n] represents the integer matrix of a given m row n column. Sub-array A[i1:i2][j1:j2] represents the upper-left and lower-right column coordinates (I1,J1) and (I2,J2) of the sub-matrix, the sum of its elements is recorded as:
The optimal value for the maximum sub-matrix problem is. If the maximum sub-matrices and problems are solved with a direct enumeration method, O (m^2n^2) time is required. Note that, in the formula,, set, then
It is easy to see that this is the largest sub-segment and problem in a one-dimensional situation. Therefore, the maximal sub-matrix and the dynamic programming algorithm can be designed with the maxsum of the maximal sub-segment and the problem dynamic programming algorithm, as follows:
//The sum of the maximal sub-matrices of 3d4-5#include"stdafx.h"#include<iostream>using namespacestd;Const intm=4;Const intn=3;intMaxsum (intNint*a);intMAXSUM2 (intMintNinta[m][n]);intMain () {intA[][n] = {{4,-2,9},{-1,3,8},{-6,7,6},{0,9,-5}}; for(intI=0; i<m; i++) { for(intj=0; j<n; J + +) {cout<<a[i][j]<<" "; } cout<<Endl; } cout<<Endl; cout<<"the maximum contiguous sub-segments of array A are:"<<maxsum2 (m,n,a) <<Endl; return 0;}intMAXSUM2 (intMintNintA[m][n]) { intsum =0; int*b =New int[n+1]; for(intI=0; i<m; i++)//pieces held { for(intk=0; k<n;k++) {B[k]=0; } for(intj=i;j<m;j++)//Enumerate initial line I, end line J { for(intk=0; k<n; k++) {B[k]+ = A[j][k];//B[k] is the sum of vertical columns intMax =maxsum (N,B); if(max>sum) {Sum=Max; } } } } returnsum;}intMaxsum (intNint*a) { intsum=0, b=0; for(intI=1; i<=n; i++) { if(b>0) {b+=A[i]; } Else{b=A[i]; } if(b>sum) {Sum=b; } } returnsum;}
The above code MaxSum2 method Execution procedure can be expressed as:
Classic question three: Finding the maximum M sub-segments and problems
Dynamic Programming Preliminary