A few days ago in the algorithm book see an integer split the topic, think very interesting, recorded as follows:
title: Given an integer n, the total number of possible outputs of this integer split
For example: N==6 has
6
5+1
4+2 4+1+1
3+3 3+2+1 3+1+1+1
2+2+2 2+2+1+1 2+1+1+1+1
1+1+1+1+1+1
A total of 11 decomposition methods, so the output should be 11. Analysis of a
Splits are arranged by factor from large to small, and each split can be considered a reduction in the size of the problem, so recursion can be used to resolve it.
Set Q (n,m) is the total number of all cases where integer n is split using an integer not less than m, so there are
1) When N==m
Can be divided into two situations, one is to use n itself, only one case. Two are split using integers that are less than n-1.
So at this time Q (n,m) =1+q (n,n-1);
2) when N<m
It doesn't make sense to use a number larger than N, so this time Q (n,m) =q (n,n)
3) When N>m
In this case there are two cases, one is to use M to split N, one is to use a number less than m to split N
For the first, using m to split N, so the largest number of split out is M, the rest of the number is added to n-m, the problem becomes using an integer less than M to split the n-m, so this time is Q (n-m,m)
For the second, split n with a number less than m, expressed as Q (n,m-1)
4) When n==1 or m==1 there is only one case, return 1. Note that it is possible to miss out on m==1, which is actually the case.
So you can use recursive functions to program the following:
#include <stdio.h>
#include <algorithm>
using namespace std;
int q (int n,int m) {
if (n==1| | M==1) {
return 1;
}
if (n<m) return Q (n,n);
if (n==m) {
return Q (n,m-1) +1;
}
if (n>m)
return Q (n,m-1) +q (n-m,m);
}
void Main () {
int n;
while (scanf ("%d", &n)!=eof) {
printf ("%d\n", Q (N,n));
}
}
Analysis Two
Using the parent function method
Integer decomposition with the parent function can be understood, respectively, with any of the 1,2,3,4,......,n can be added up to represent the number of N. And because when the integer m is used to decompose N, the number of times used cannot be more than n/m, so you can write the following parent function:
G (x) = (1+x^1+x^2+......+x^n) * (1+x^2+x^4+......+x^ ((N/2)) * ...
* (1+x^m+x^ (2*m) +x^ (3*m) +......+x^ ((n/m) *m)) *......* (1+x^n)
Using the set array in the program to represent the coefficients for each round of multiplication, the C array represents the sum of the coefficients multiplied by the multiplication so far. Finally, the corresponding coefficients of x^n are the possible number of decomposition. The code is as follows:
#include <stdio.h>
const int num=1000;
int Set[num];
int C[num];
void Init () {for
(int i=0; i<num; i++) {
c[i]=1;
set[i]=0;
}
}
int main () {
int n;
int sum;
Init ();
while (scanf ("%d", &n)!=eof) {
sum=0;
Init ();
for (int i=2, i<=n; i++) {for
(int. j=0; j<=n; j+=i) {for
(int k=0; j+k<=n; k++) {
set[k+j]+=c[k];< c20/>}
} for
(int x=0; x<=n; x + +) {
c[x]=set[x];
set[x]=0;
}
}
printf ("%d\n", C[n]);
}
return 0;
}
Topic Two: Given an integer n, output the possible form of the integer split (that is, the output of all cases)
Use recursion (the output is really troublesome.) For a long time (>﹏<))
The entire output is similar to a tree, to decompose 6 as an example, the process is shown below
The code is as follows:
#include <stdio.h>//Use an array to record the value generated in the recursive process before the duplicate output is required int set[100];
Used in recursive process to determine whether recursion to the deepest, output enter int k; This function represents the case where n is split with an integer that is not more than M, and I is used to denote the length of records already present in the set array, void Q (int n,int m,int i) {if (n==k&&n!=m) {//At this time the recursive stack has been returned to the top of a branch
Layer, output Enter//reset counter I to 0 printf ("\ n");
i=0;
} if (n==1) {///when n is 1, meaning that only 1 printf ("1") can be represented;
Return
The else if (m==1) {///when M is 1, means to output N m to add for (int i=0; i<n-1; i++) printf ("1+");
printf ("1");
Return
} if (n<m) {q (n,n,i);
if (n==m) {////when n equals m, a leaf that arrives at this recursive sum is required to output more than one space, indicating that the next output is another leaf printf ("%d", n);
Output the number of previous records above the leaf before recursively outputting another leaf, as shown in procedure 1 for (int j=0; j<i; j + +) printf ("%d+", Set[j]);
Q (n,m-1,i);
if (n>m) {///if n is greater than M, use m as decomposition, first output m+ form printf ("%d+", m);
Record the value of m as the trunk node and make I self-increment set[i++]=m;
Recursive output m+ after decomposition Q (n-m,m,i);
After the recursion is completed, the array record needs to be back one, back to the previous node, as shown in procedure 2 i--;
Executes another branch, outputting the recorded data before the next recursion, as shown in procedure 3 for (int j=0; j<i; j + +) printf ("%d+", Set[j]);
Recursive output Another branch condition Q (n,m-1,i);
}} void Main () {int n; while (sCANF ("%d", &n)!=eof) {if (n<=0) {printf ("Please input a positive interger.\n\n");
Continue
} k=n;
Q (n,n,0);
printf ("\ n"); }
}