"Problem description" the split of natural number: any one of the natural number greater than 1 N,
Can always be divided into several natural numbers of the sum, and there are many methods of splitting. Try to find all the split of N.
For example, natural number 5, you can have some of the following splitting methods:
5=1+1+1+1+1
5=1+1+1+2
5=1+2+2
5=1+4
5=2+3
The algorithm is implemented by backtracking method.
For the given problem, define the solution space of the problem, as in the case of the 5 split,1<= split the number of <=5.
determine the spatial structure of the solution used for searching, as in the case of a split of 5 , a x[ ] array is used to store the solution, and the range of values for each array element is 1<= the number of splits <=5 , from 1 Start searching until 5 .
Search the solution space and use pruning functions to avoid invalid searches during the search process.
In the case of a 5 split, in order to avoid duplication, X[i] >= x[j] (i > J), such as x[]={2,3} meet the conditions and x[]={3,2} /c0> is not satisfied with the condition is not feasible solution is invalid .
1#include <stdio.h>2#include <stdlib.h>3 4 voidSPLITN (intNintm);//N is the number that needs to be split, and M is the progress of the split. 5 intx[1024x768]={0},total=0;//total number of methods used to count splits, x[] for storing solutions6 voidMain ()7 {8 intN;9printf"Please input the natural number N:");Tenscanf"%d",&n); OneSPLITN (N,1); Aprintf"there is%d ways to split natural number%d.", total,n); - } - the voidSPLITN (intNintm) -{//N is the number that needs to be split, and M is the progress of the split - intrest,i,j; - for(i=1; i<=n;i++) +{//try splitting starting from 1 - if(i>=x[m-1]) +{//the number of splits is greater than or equal to the previous one thereby guaranteeing no repetition AX[m]=i;//Count This number into the result atRest=n-i;//The remaining number is n-i, if there is no left, and the progress (total number of split) is greater than 1, the explanation has been a result - if(rest==0&&m>1) - { -total++; -printf"%d\t", total); - for(j=1; j<m;j++) in { -printf"%d+", X[j]); to } +printf"%d", X[m]); -printf"\ n"); the } * Else $ {Panax NotoginsengSPLITN (rest,m+1);//Otherwise the remaining number will progress to m+1 split - } thex[m]=0;//cancels the result and makes the next split. Environmental recovery, that is, backtracking + } A } the}
View Code
Implementation of the algorithm two-use recursive return
Using incomplete inductive method
n =2 can be split into 2 = 1 +1
n =3 can be split into 3 = 1 +2 = 1 +1 +1
n =4 can be split into 4 = 1 +3 = 1 +1 +2 = 1 +1 +1 +1 = 2 +2
......
n =7 can be split into 7=1 +6
=1 +1 +5
=1 +1 +1 +4
=1 +1 +1 +1 +3
=1 +1 +1 +1 +1 +2
=1 +1 +1 +1 +1
=1 +1 +1 +2 +2
=1 +1 +2 +3
=1 +2 +4
=1 +2 +2 +2
=1 +3 +3
=2 +5
=2 +2 +3
=3 +4
A split of N is done with array a storage. From the analysis of the incomplete inductive method above n = 7 o'clock,
According to A[1] classification, there are a[1]=1,a[1]= 2,...,a[1]= N/2, a total of n/2 large categories of split.
In each class of split, a[1]= I, a[2]= n-i, starting from k=2, from A[k] continue to split,
A[K] can be split again depending on whether the A[K]/2 is greater than or equal to a[k-1].
The parameter T of the recursive procedure points to the number to split A[k]
1#include <stdio.h>2#include <stdlib.h>3 4 inta[ -]={0};5 voidSplit (intt)6 {7 inti,j,l;8 for(i =1; I <t; i++)9 {Tenprintf"%d+", A[i]); One } Aprintf"%d\n", A[i]); - -j =T; theL =A[j]; - for(i = a[j-1]; I <= L/2; i++) - { -A[J] =i; +a[j+1] = L-i; -Split (j+1); + } A } at - voidSplitnum (intN) - { - inti; - for(i =1; I <= n/2; i++) - { ina[1] =i; -a[2] = n-i; toSplit (2); + } - } the intMain () * { $ intN;Panax Notoginsengscanf"%d",&n); - splitnum (n); the return 0; +}
View Code
Reference: Http://wenku.baidu.com/link?url= H7tdqvemnds9sn4ffuwmw8m6afamul44-vcr83z4lkv9un-hau159gjtfr5m48t11xbjfmwp3i4qpk6u2wheorzdeyhrabqt63zvadunsai
The splitting of natural numbers