*************************************** Reprint Please specify the Source: Http://blog.csdn.net/lttree ********************************************
This weekend home a little something, back to the home, there are some learning plans broken.
Hurry up and fill up!
The first algorithm--recursion and partition
All know, the basic idea of divide and conquer algorithm is
Divide a problem that is difficult to be solved directly into the same problem of small scale, so as to conquer, divide and conquer,
In this way, we can make a complex algorithm, the type is unchanged, the size of the smaller, and finally makes the sub-problem easy to solve, which leads to recursive algorithm.
In fact, division and recursion like a pair of twin brothers, often can be used at the same time in the algorithm design, and thus produce many efficient algorithms.
First, recursion
concept: direct or indirect invocation of the algorithm called the recursive algorithm, a function defined by the function itself is called a recursive function.
A few classic examples of recursion are listed below:
① factorial
Defined:
N! equals 1 when n=0
equals N (n-1)! when n>0
int factorial (int n) { if (n = = 0) return 1; Return n*factorial (n-1);}
②fibonacci Series
An infinite sequence of sequences of: 1,1,2,3,5,8,13,21,34,55 ....
Defined as:
F (n)=1 when n=0
=1 when n=1
=F (n-1) +f (n-2) when n>1
<span style= "FONT-SIZE:18PX;" >int Fibonacci (int n) { if (n <= 1) return 1; Return Fibonacci (n-1) +fibonacci (n-2);} </span>
③ackerman function
This is a double recursive function, and when a function and one of its variables are defined by the function itself, the function is called a double recursive function.
Ackerman function A (N,M) has two independent integer variable m≥0,n≥0, which is defined as follows:
A (1,0)= 2 m≥0
A (0,m)= 1 n≥2
A (n,0)= n+2 n≥2
A (n,m)= A (A (n-1,m), m-1)n,m≥1
int Ackerman (int n, int m) { if (n==1 && m==0) return 2; if (n==0) return 1; if (m==0) return n+2; Return Ackerman (Ackerman (n-1,m), m-1);}
④ permutation problems
A full array of n elements,
When N=1, Perm (P) = (R), where r is the only element in set R
When N>1, Perm (P) is composed of (R1) Perm (R1), (R2) Perm (R2), ..., (RN) Perm (RN)
template< class Type >inline void Swap (type& a,type& b) { Type temp = A; A = b; b = temp;} void Perm (Type list[],int k, int m) { if (k==m) {for (int i = 0; I <= m; ++i) cout<<list[i];< c10/>cout<<endl; } else {for (int i = k; I <= m; ++i) { Swap (list[k],list[i]); Perm (list,k+1,m); Swap (List[k],list[i]);} }
⑤ Integer Partitioning problem
Represents a positive integer n as the sum of a series of positive integers,
N=n1+n2+...+nk (where n1≥n2≥n3≥ ....) ≥NK)
For example, for the division of Integer 6:
6
5+1
4+2 4+1+1
3+3 3+2+13+1+1+1
2+2+2 2+2+1+12+1+1+1+1
1+1+1+1+1+1
A total of 11 divisions
The following recursive relationship can be established according to the number of partitions with maximum addend N1 not greater than M as Q (n,m):
<1> Q (n,1) = 1, n≥1--when the maximum addend N1 is not greater than 1 o'clock, any positive integer n has only one form of partitioning
<2> Q (n,m) =q (n,n), n≥m--maximum addend N1 actually cannot be greater than N. So Q (1,m) =1
<3> Q (n,m) =q (n,m-1) +q (n-m,m), n>m>1--positive integer n the maximum addend N1 is not greater than the division of M is composed of N1=m and N1≤m-1 division.
To sum up, we can summarize:
Q (n,m) =
1 N=1,m=1
Q (n,n) n<m
1+q (n,n-1) n=m
Q (n,m-1) +q (n-m,m) n>m>1
int q (int n, int m) { if (n<1) | | (m<1)) return 0; if ((n==1) | | | (m==1)) return 1; if (n==m) return Q (n,m-1) +1; return Q (n,m-1) +q (n-m,m);}
⑥hanoi Tower Problem
A very classical recursive problem, the problem is not to repeat, the direct write algorithm:
void Hanoi (int n, int a, int b, int c) { if (n > 0) { Hanoi (n-1,a,c,b); Move (A, b); Hanoi (N-1,c,b,a); }}
Ii. Division and Treatment
It has also been said that the basic idea of dividing the law is to divide the problem of a large scale into small-scale problems that are independent and identical to the original problem.
Its algorithm design pattern is as follows:
Divide-and-conquer (P) { if (| p| <= n0) adhoc (P); Divide P into smaller subinstances p1,p2,p3,..., Pk; for (i = 1; I <= K; ++i) Yi = Divide-and-conquer (Pi); Return merge (Y1,y2,..., yk);}
This one
| p| Indicates the size of the problem p,
N0 is a threshold value, indicating that the current problem P scale does not exceed n0, the problem is easy to solve, no longer need to continue decomposition.
Adhoc (P) is the basic sub-algorithm in the division method, which can be directly solved for the problem of easy solving.
Merge (Y1,y2...yk) is a merging sub-algorithm for solving y1,y2 of P's sub-problem p1,p2,...,pk,..., yk merging to P.
The computational efficiency of divide-and-conquer method is usually analyzed by recursive equation, for the above design pattern, solution | The calculation time required for the p|=n problem is:
T (n) = O (1) when N=1
KT (n/m) +f (n) when n>1
These are some of the basic ideas and principles of recursion and division, and the next blog post will have specific examples to illustrate.
*************************************** Reprint Please specify the Source: Http://blog.csdn.net/lttree ********************************************
The way to regain the algorithm--the basis of recursion and partition