recursive: The algorithm that calls itself directly or indirectly .
EG:
1 "factorial definition n!=n (n-1)! (n>0);
Pubic static int factorial (int n) { if (n==0) return 1; else return n*factorial (n-1);}
2 "Fibonacci Series
public static int Fibo (int n) {if (n<=1) return 1; else Fibo (n-1) +fibo (n-2);}
3 "permutation problem (full arrangement of a set)
Set P (x) to represent the full arrangement of the set X, the RP (x) represents the full arrangement of the collection {r,x}, then the full arrangement of a collection can be recursively recursive to the full array of only one element's collection.
Set RI to represent R-{ri}, then P (R) = (r1) p (R1), (R2) p (R2),...... (RN) p (RN);
public void Perm (char *list,int k,int m) {//Generate LIST[K:M] full permutation if (k==m) {////Only one element left when for (int =0;i<=m;i++) {printf ("%c", List[i]);} printf ("\ n");} else{//There are many more elements, recursively producing permutations for (int i=k;i<=m;i++) {//putting each element of the collection in the first line of the queue, recursively. Swap (list,k,i);//Exchange position perm (LIST,K+1,M);//recursive swap (list,k,i);//Recover In Situ}}}
4 "Integer Division Problem
Represents a positive integer n as the sum of a series of positive integers, n=n1+n2+.....nk, where n1>=n2>=....nk>=1,k>1;
This representation becomes the division of a positive integer n, denoted by P (n), the number of partitions with a maximum addend N1 not greater than M is recorded as Q (n,m).
Analysis:
1 if n=1, regardless of M-value, there is only one division {1};
2 "If m=1, no matter n what value, only one division {1,1,1,1,1 ...};
3 "If n<m, because there is no negative number exists, so f (n,m) =f (n,n);
4 if n=m, it can be divided into two kinds of situations to discuss:
A is divided into M (=n), so there is only one partition, {n};
b The division does not contain m, that is, the maximum can only be m-1, that is, f (n,m-1);
5 "If n>m, there are two kinds of situations to discuss
A partition contains M, then {m,{m1,m2,m3 ...}}, or F (n-m,m);
B "in the division is not good m, then f (n,m-1);
Comprehensive:
F (n,m) =1,n=1orm=1
F (n,m) =f (n,n)n<m
F (n,m) =1+f (n,m-1)n=m
F (n,m) =f (n-m,m) +f (n,m-1)n>m
#include <iostream>using namespace Std;int f (int n,int m) {if (N==1 | | M==1) return 1;else if (n<m) return F (n,n), else if (n==m) return (1+f (n,m-1)), else {return (f (n-m,m) +f (n,m-1));}} int main () {int n,m;scanf ("%d%d", &n,&m);p rintf ("result=%d\n", F (n,m)); return 0;}
5 "The question of the Nottingham Tower.
Consider the movement of the two-storey tower first, and find that three actions are needed. Consider that the movement of the three-storey tower, the discovery of a certain repetition, the above two layers as a whole, and change layer two-storey tower movement, and so on, found that any n-level movement can be divided into the nth layer and the front (n-1) layer recursion.
public void Hanoi (int n,int a,int b,int c) {//n represents the total number of layers, moving from a through C to Bif (n>0) {Hanoi (n-1,a,c,b); Move (A, b); Hanoi (N-1,C,BA);}}
Summarize:
1 "must have a termination condition, or fall into infinite recursion, the last stack overflow.
2 "Consider whether it is possible to solve with recursion, think about whether reducing the size of the problem can take the same steps and the result of the next step depends on the result of the previous step to produce recursion. Can also start from the simplest case, gradually expand the law of discovery of scale.
Second, divide and conquer: the problem of a scale n is decomposed into K small sub-problems and independent and the same as the original problem, recursion solves the sub-problem, then merges the solution of the original problem.
Divide-and-conquer (P) {if (| p|<=n) adhoc (p);d ivide P into p1,p2,p3...pk;for (int i=1;i<=k;i++) yi=divide-and-conquer (pi); return merge ( Y1,y2....yk);}
where n time threshold, when the size of the problem reaches the threshold, you can directly get the solution and return the solution
1 "Binary Search algorithm
Thought: Search for an element in an ordered array, narrowing the range by one comparison (the median of the value range, i.e. (left+right)/2), until the element is found or no solution. Because each search decreases by half, the complexity is O (logn).
(Reduction of scale, repetition of solution steps, determination of threshold)
Binary finds//a as an ordered ascending array, K is the element to find, n is an array size int f (int *a,int k,int n) {int left=0,right=n-1;while (left<=right) {int mid= (left+ right)/2;if (k = = A[mid]) {return mid;} else if (K<a[mid]) {right=mid-1;} else{left=mid+1;}} return-1;//not Found}
2 "Merging algorithm (merge algorithm)
Thought: To sort the elements of the atmosphere two roughly the same size of 2 sub-sets, respectively, to sort the two sub-sets, and finally merge the sorted subset into the desired sort set. (Reduce the size by half N/2, and the small-scale solution as above, until only one element remains)
void Mersort (int *a,int n) {//n array length int *p= (int *) malloc (sizeof (int) * (n+1));
Resolution of the problem requires a temporary array, the temporary array is assigned only once, and the overhead mergesort (a,0,n-1,p) is reduced;} partition void mergesort (int *a,int left,int right,int *p) {//left,right all indicate subscript if (left<right) {int mid= (left+right)/2; MergeSort (a,left,mid,p); MergeSort (a,mid+1,right,p); merge (a,left,mid,right,p);} else{}}//merge void merge (int *a,int left,int mid,int right,int *p) {int I=left,j=mid+1;int pp=left;while (I<=mid & & J<=right) {if (A[i]<a[j]) {p[pp++]=a[i];i++;} else {p[pp++]=a[j];j++;}} while (I<=mid) {p[pp++]=a[i++];} while (J<=right) {p[pp++]=a[j++];} /* Test validation for (int h=left;h<=right;h++) {printf ("%d,", p[h]); a[h]=p[h];} printf ("\ n"); */}
3 "Quick Sort
Thought: Select an element to be sorted and divide it, put it on the right side, and put it on the left, the rest is its position. Reduce problem size continuously
int p (int *a,int left,int right) {int key=a[left];//printf ("* * * * * * * ", a[left]); while (left<right) {// Move to the left while (left<right && A[right]>=key) right--;a[left]=a[right];//larger than key to the right while (left< Right && A[left]<=key) left++;a[right]=a[left];} When the left==rght position is the position of the key//printf ("a[%d]=%d\n", Left,key); A[left]=key;return left;} void QSort (int *a,int left,int right) {if (left<right) {<span style= "White-space:pre" ></span>// Recursive termination conditions must not forget, painful lessons int pp=p (a,left,right); QSort (a,left,pp-1); QSort (a,pp+1,right);}}
4 "Multiplication of large integers
Idea: The large integer is divided into two paragraphs, each paragraph N/2 bit, then x=a*2^n/2+b,y=c*2^n/2+d, after multiplying the parentheses can get xy=ac*2^n+ (AD+BC) *2^n/2+bd;
T (N) ={o (1), n=1; 4T (N/2) +o (n), n>1;}
A mathematician's improvement found xy=ac2n+[(A-B ) (d-c) +ac+bd]2n/2+bd
T (1) =1
T (n) =3t (N/2) +cn.
#define SIGN (num) (num) >0?1:-1;//x and y are all n-decimal large integer multiplication models//To implement a true large integer, change the data structure to an array storage int Mul (int x,int y,int n) {int s=sign (x *sign (y), int x=abs (x), int y=abs (y), if (x==0 | | y== 0) return 0;if (n==1) {return x*y;} Else{int xl=x/(int) pow (int) n/2), int xr=x-x1* (int) pow (int) n/2), int yl=y/(int) pow ((int) n/2), int yr=y-y1* ( int) pow ((int) n/2); int M1=mul (XL,YL,N/2); int M2=mul (XR,YR,N/2); int M3=mul (XL-XR,YL-YR,N/2); return s* (m1* (int) POW (10,n) +m3*m1*m2* (int) pow (10,N/2) +m2);}}
More Content Reference blog: http://blog.chinaunix.net/uid-20563078-id-1636245.html.
PS: For a solution that is not a divide-and-conquer algorithm, we generally use a linked list or array to store data, imitating the manual vertical calculation method, but each time only 2 one decimal number multiplied by the efficiency is too low, improved version one is the use of a list method (Reference blog: http://blog.csdn.net/ zxasqwedc/article/details/12399543)
You can use the multiplication of thousands, the large integer is divided into each element is a no more than 1000 of the three-bit decimal number, each multiplication is three-digit three-digit multiplication, the specific view of this blog http://www.xuebuyuan.com/1601102.html.
To solve the problem: what is the complexity of dividing a large integer into multiple segments instead of 2 segments? is better than 2 segments????
5 "Stassen matrix multiplication
The advanced mathematics question, writes out is also just the porter, directly posts the reference blog The connection: http://blog.sina.com.cn/s/blog_6eea1bc20100mfp3.html.
6 "board cover
Problem description
In a chessboard of 2^kx2^k squares, a square is different from the other squares, calling it a special square and calling the chessboard a special chessboard. In the problem of board coverage, the 4 different forms of the L-shaped dominoes are used to cover all squares on a given special chessboard except for special squares, and any 2 L-type dominoes must not overlap.
Idea: This provides the key or to understand a little bit of skill, the two sub-problems into a sub-problem. According to divide and conquer thought is square, ought to divide it into four small square, namely 4 2^k-1*2^k-1 of sub-chessboard. Special squares are located in one of the remaining three non-special squares, in order to convert it into a special box, you can use an L-type Domino cover 3 chessboard of the junction, which translates into 4 special checkered board coverage problem. Recursive return is stopped when the last checkerboard has only one square. To represent the coverage method, the dominoes are numbered.
#include <stdio.h> #include <stdlib.h> #include <string.h> #define SIZE 100int tile=0;int board[size][ size];//Checkerboard//TR,TC is the upper left-hand corner of the chessboard, the column number. DR,DC is a special grid row number, column number//size is the checkerboard size void chessboard (int tr,int tc,int dr,int dc,int size) {if (size = = 1)//stop recursive Return;int t=tile++ ;//Domino designator int s=size/2;//split checkerboard//upper left corner checkerboard if (dr<tr+s && dc<tc+s) {//special squares in this chessboard (tr,tc,dr,dc,s);} else{board[tr+s-1][tc+s-1]=t;//Add Special Squares chessboard (tr,tc,tr+s-1,tc+s-1,s);} upper right corner checkerboard if (dr<tr+s && dc>=tc+s) {chessboard (tr,tc+s,dr,dc,s);} Else{board[tr+s-1][tc+s]=t;chessboard (tr,tc+s,tr+s-1,tc+s,s);} Lower left corner if (dr>=tr+s && dc<tc+s) {chessboard (tr+s,tc,dr,dc,s);} Else{board[tr+s][tc+s-1]=t;chessboard (tr+s,tc,tr+s,tc+s-1,s);} Lower right corner if (dr>=tr+s && dc>=tc+s) {chessboard (tr+s,tc+s,dr,dc,s);} Else{board[tr+s][tc+s]=t;chessboard (tr+s,tc+s,tr+s,tc+s,s);}} void Main () {memset (board,0,sizeof (board)); Board[3][3]=100;chessboard (1,1,3,3,16); for (int. i=1;i<=16;i++) {for ( int j=1;j<=16;j++) printf ("%4d", Board[i][j]);p rintf ("\ n");} printf ("\ntile=%d\n", tile);}
7 "Round robin Calendar
There are n=2k players competing to design a match schedule that meets the requirements:
(1) Each contestant must compete with the other n-1 players once;
(2) Each contestant can only race once a day.
According to this request, the tournament schedule can be designed as a two-dimensional table of n-row n-1 columns, where section I of row J indicates the contestants of the first I race on the J Day.
The idea is still to find a solution that can be repeated, and this is the answer
#include <stdio.h> #include <stdlib.h> #include <string.h> #define SIZE 100int a[size][size];void Table (int k,int a[][size]) {int Temp;int n=2;//first n=2, two person case a[1][1]=1;a[1][2]=2;a[2][1]=2;a[2][2]=1;for (int t=0;t <k;t++) {Temp=n;n=n*2;int i,j;//add the lower left corner data for (i=temp+1;i<=n;i++) {for (j=1;j<=temp;j++) {A[i][j]=a[i-temp][j] +temp;}} Add the lower right corner data for (i=temp+1;i<=n;i++) {for (j=temp+1;j<=n;j++) {a[i][j]=a[i-temp][j-temp];}} Add the upper right corner data for (i=1;i<=temp;i++) {for (j=temp+1;j<=n;j++) {a[i][j]=a[i+temp][j-temp];}}} void Main () {table (3,a), for (int i=1;i<=8;i++) {for (int j=1;j<=8;j++) printf ("%4d", A[i][j]);p rintf ("\ n");}}
Attached to two reference blogs, the wording is slightly different, not yet I fully understand
1: Recursive notation http://www.2cto.com/kf/201411/351886.html
2:http://blog.csdn.net/liufeng_king/article/details/8488421
See the following code for an explanation of blog links 2
Idea: This algorithm turns the whole arrangement from the previous three steps into two steps: The algorithm is originally filled with two people match the arrangement, then start 1) The upper left corner copied to the lower right corner, 2) the upper left corner of the value added to the lower left corner, 3) the lower left corner copied to the upper right corner. Algorithm two now fill the first row of data, then press 1 to copy the upper left corner to the lower right corner, 2) to the lower right corner.
Comparison: Algorithm one is more intuitive and easy to understand.
#include <stdio.h> #include <stdlib.h> #include <string.h> #define SIZE 100int a[size][size];void Delay (int a[][size],int k) {int n=1;for (int i=1;i<=k;i++)//Checkerboard Total size n=n*2;for (i=1;i<=n;i++) {for (int j=1;j<=n;j+ +){
<span style= "White-space:pre" >if (a[i][j]!=0) </span><span style= "White-space:pre" ></span> printf ("%4d", A[i][j]);} printf ("\ n");} printf ("\ n");} void table (int k,int a[][size]) {int n=1;for (int i=1;i<=k;i++)//Checkerboard Total size n=n*2;for (i=1;i<=n;i++)//Fill first row a[1][i]=i; int m=1;for (int s=1;s<=k;s++) {//per twice times increase, only k times can fill n=n/2;for (int t=1;t<=n;t++) {//Each row fills m column of data, total need n times for (int i=m+1 ; i<=2*m;i++) {for (int j=m+1;j<=2*m;j++) {a[i][j+ (t-1) *2*m]=a[i-m][j+ (t-1) *2*m-m];//fills the upper-left corner data into the lower-right corner a[i][j+ (t-1) *2*m-m]=a[i-m][j+ (t-1) *2*m];//upper right corner data is populated to the lower left corner}}//This snippet of code helps to understand the algorithm operation process printf ("t=%d\n", T);d Elay (a,k);} m=m*2;//multiplication}}void Main () {table (3,a);}
8 "Linear Time selection
9 "Closest point to the problem
Algorithm design and Analysis Note (i) recursion and divide-and-conquer strategy