Recursive basis zoned classification _ _ integer multi-state transfer complex recursive search & Memory

E: integer divide problem Title Description 

The positive integer n represented as a series of positive and integer, n = n 1 + n 2 +... + Nk, where n 1 ≥ n 2 ≥ n 3 ≥... ≥ nk ≥ 1, k ≥ 1.
This represents a positive integer n is a positive integer n is called divided, dividing the number of different positive integer n is called a division number n, a positive integer, denoted by p (n).
For example, following a positive integer of 6 to 11 different division, so that p (6) = 11.

6 = 6;
6 = 5 + 1;
6 = 4 + 2;
6 = 4 + 1 + 1;
6 = 3 + 3;
6 = 3 + 2 + 1;
6 = 3 + 1 + 1 + 1;
6 = 2 + 2 + 2;
6 = 2 + 2 + 1 + 1;
6 = 2 + 1 + 1 + 1 + 1;
6 = 1 + 1 + 1 + 1 + 1 + 1;

Enter a description

A plurality of sets of data, each set of data comprising a positive integer n (1 ≤ n ≤ 20).

Output Description

Each data output line, comprising a positive integer k, n represents a positive integer division number.

Sample input

1
2

Sample Output

1
2

answer:

This problem class, the teacher with the way is recursive, and Tower of Hanoi and is not the same, in addition to its state transition equation recursive "whole law", step by step can be easily represented, such recursion has almost come to realize recurrence ,

Direct rule of law to find the sum can not find, and set the sum as an argument to do more troublesome equation of state, the situation will be repeated screening, the analog approach

6 = 6;


6 = 5   + 1;  (dp【1】【j】)


6 = 4   + 2;
6 = 4   + 1   + 1; (dp【2】【j】)


6 = 3   + 3;
6 = 3   + 2   + 1;
6 = 3   + 1   + 1   + 1; ( dp【3】【j】)


6 = 2   + 2   + 2;
6 = 2   + 2   + 1   + 1;
6 = 2   + 1   + 1   + 1   + 1;   (dp【4】【j】-  k)


6 = 1   + 1   + 1   + 1   + 1   + 1; (dp【5】【j】-k)

In addition to multiple states to consider this question to find the law process is the most important find in what way it is looking to the back, so that there will be no repeat of the situation appears 

 

Further examples of n = 6 subject to the tips, i.e. from 5-1, and the latter must be less than equal to the number before a number (an> = an + 1), limit the number n of the final decomposition 

This is the example, to give examples of the solution - not a direct simulation, but simulation of the search tree,

But it does not need to traverse to the end, and then write down all the leaf nodes,

Its approach is to count the number of branches, each encounter with branches on +1, then recursively Next, return the number of branches after the add

- state transition equation of the solution to a problem, direct binary variable is set to the number F (a, b), the resulting sequence of output target, a predetermined standard or less where b

f(n, m) = 1;                      ( n = 1 or m = 1 )

f (n, n); (n <m) // n itself divided

1+ f (n, m - 1); (n = m) // 1 operation needed to change

f(n - m, m) + f(n, m - 1);   ( n > m )//

Claim

 First determine the argument, and then - the number of split Method - classification discussed, based on the size relationship between the number of split m and n _ can be divided,

  • Eventually happen to have a 1, this time to find a branch
  • n = m, but less than 1, not in the end, so that a section where shrinkage
  • A is 1, n-1 or is a m-1,
  • And a situation difficult to think 4, and m is a nm, exactly complementary relationship, then other n constant, variable m

 In the recursive process, constantly broken down into two, but it was two variables are handled automatically,

Somewhat similar to the "binary search" - a little partition of meaning in it, (this concept is now not very skilled, after another make up)

Code:

 1 #include <iostream>
 2 #include <cstring>
 3 #include <queue>
 4 #include <cstdio>
 5 #include <cmath>
 6 #include <map>
 7 #include <algorithm>
 8 typedef long long ll;
 9 using namespace std;
10 int n1;
11 int sum=0;
12 
13 int f(int m,int n) {
14     if(m==1||n==1) {
15          return  . 1 ;
 16      }
 . 17      IF (m == n-) {
 18 is          // At this time there is a need to do the job changes 
. 19          return F (m, M- . 1 ) + . 1 ;
 20 is  
21 is      }
 22 is      IF (m < n-) {
 23 is          return F (m, m);
 24  
25      }
 26 is      IF (m> n-) {
 27          return F (Mn, n-) + F (m, N- . 1 );
 28      }
 29  
30  
31 is  }
 32  
33 is  
34 is  
35 int main () {
 36  
37 [      the while (CIN >> N1) {
 38 is          COUT << F (N1, N1) << " \ n- " ;    // most does not exceed n- 
39      }
 40  
41 is  
42 is  
43 is  
44 is      return  0 ;
 45  
46 }
View Code

Then this is the idea I did not do it, if you do not see the solution to a problem, the provisions of recursive do, at the beginning would think so, each fixed a:

Set f (a, n) n is an exploded finally obtained sequence (the entire sequence as a state, or argument) n represents the final decomposed into at most n-1;

f (a, n) = {n: (n = a) || a-1 + f (n-a + 1) :( a = n-1, n-2, n-3, ····, 1), (required, a> = f (na) of any elements)} 

A1 corresponds to 1 from the n-up test, a1 fixed, split-a1 n, then re-fixed a2, n-a1-a2 removed until the n-a1-a2-an, 1 is returned to trial

However, and. No. Have. do it.

Currently Reflection: because the boundary conditions are set here is ambiguous, a = 1 is not clear, this condition can not be guaranteed because the summed value sum == n

The reason might be to draw up, thinking both analog division to do, and think - search (third step is equivalent dfs) ​​to do, confused thinking, not very understanding of mixed flow, return precondition set incorrectly. ,

 

It also usually do not how to do, this problem obviously can remember finishing up search, and just that idea is similar to writing a dfs way,

Whether in the end return before division manner with the prerequisites and determines whether n

However, determination conditions were changed, and so the current sum automatically pop stack, sum-stack, as the back layer,

 1 #include <stdio.h>
 2 #include <iostream>
 3 # define MAXN 100
 4 using namespace std;
 5 int mark[256];
 6 int n;
 7 int len=0;
 8 int sum=0;
 9 void DFS(int k, int pr) {
10     if(sum > n) {
11         return;
12     } else if(sum == n) {
13 is          len ++ ;
 14  
15      } the else {
 16          for ( int J = PR; J> 0 ; J, ) {
 . 17              Mark [K] = J; // assignments are not directly covered by the pop-up 
18 is              SUM = + J;
 . 19              the DFS ( + K . 1 , J);
 20 is              SUM - = J;
 21 is          }
 22 is      }
 23 is  }
 24  int main () {
 25      the while (CIN >> n-) {
 26 is          SUM = 0;
27         len=0;
28         DFS(0,n);
29         cout<<len<<"\n";
30     }
31     return 0;
32 }
View Code

As bfs realize, understand, currently the subject requirements have limited the width, depth inspection required = 1 (no recursion to the last on it), width traversing advantage does not exist, does not need pruning

dp idea - based on my current understanding of dp

A general is the use of two-dimensional array, the problem will be converted to two-dimensional array of the search tree - the relationship between binary variables, the general difficulty to find and define the relationship between dp [i] [j], the recursive find

This question asks the total number of division n, readily appreciate readily occur, a large partitioning can be divided into smaller, thereby adding to the total number may be, but note can not be repeated,

Namely : dp [i] can be defined as the total number of integer division when i 

6 = 6;

6 = 5   + 1;  (dp【1】=1)

6 = 4   + 2;
6 = 4   + 1   + 1; (dp【2】=2)

6 = 3   + 3;
6 = 3   + 2   + 1;
6 = 3   + 1   + 1   + 1; ( dp【3】=3)

6 = 2   + 2   + 2;
6 = 2   + 2   + 1   + 1;

6 = 2   + 1   + 1   + 1   + 1;   (dp【4】-  k = 3 )

6 = 1   + 1   + 1   + 1   + 1   + 1; (dp【5】-   k = 1)

There is another, two-dimensional array dp method: https://blog.csdn.net/qq_31975227/article/details/68191053

 

The second not quite understand this, look back and see, is not easy to think of it, remember search more practical.

 

Guess you like

Origin www.cnblogs.com/KID-yln/p/12530936.html