trying to write a recursive function that counts the number of sequences that sum up to that number C++

后端 未结 6 1532
野趣味
野趣味 2021-01-20 02:01

Okay, so here is what I\'m trying to do. The user inputs a number. I\'m trying to write a recursive function that counts the number of sequences that sum up to that number (

相关标签:
6条回答
  • 2021-01-20 02:27

    These are called Integer Partitions, and there is a simple way to calculate the number of partitions of any number using an intermediate function. Take a look here: Integer Partition.

    0 讨论(0)
  • 2021-01-20 02:30

    Hint: try to find a function that gives the number of sequences with sum n and terms not larger than k.

    EDIT:
    Forgive me if this sounds harsh, but... your updated code is all wrong. It's hard to see what you intended. I can guess, but that would be pointless.

    Here's what I had in mind: a sequence should be in nonincreasing order, like "2 2 1 1 1 1". So how many such sequences add up to 6? Well, find the number of such sequences starting with 1, then the number of sequences starting with 2, and so on up to 6, and add them up. And how many sequences start with 2 and add up to six? (This is where the recursion comes in.) In each such sequence, the first term is 2 and the rest add up to 4 with no term exceeding 2, so we must find the number of sequences adding up to 4 with no term greater than 2. So write the signature first, then the iteration loop, then the recursive call and you're done.

    EDIT:
    All right, here's everything but the loop:

    int partition(int n, int max)
    {
      if(n==0)
        return(0);
      int ret = 0;
      if(n<=max)
        ret=1;
      for(...)
      {
        ...
      }
      return(ret);
    }
    

    Can you fill in the blanks?

    0 讨论(0)
  • 2021-01-20 02:36

    Let f(n) be the function we want, that generates sequences of integers that add to n, without permutations

    Define

    f(n) = g(n,n)

    g(n,p) = { i \in 1..min(n, p): [i g(n-i,i)] }

    0 讨论(0)
  • 2021-01-20 02:36

    The algorithm is well covered in this question.

    0 讨论(0)
  • 2021-01-20 02:40

    i think it is close to the probability theory
    amount of combinations of set {1,2,3,4,5,6} giving summary 6

    0 讨论(0)
  • 2021-01-20 02:42

    Define P(n) as the number of ways to partition n, restricting n to be an integer, n >= 1.

    Define p(n, k) as the number of ways to partition n using numbers no larger than k, restricting k to be an integer, k >= 1, k <= n.

    It follows that P(n) = sum (i: 1..n) p(n, i).

    To find p(n, k), first note that we neatly avoid double-counting by simply keeping the partition sorted: take the largest chunk first. So the first chunk may have any size from 1 up to k, and then the rest of the chunks must account for the rest of the total n, and be no larger than the first chunk.

    Thus p(n, k) = sum (i: 1..k) p(n - i, i).

    As a base case, p(1, 1) = 1.


    A sample implementation, very much not guaranteed to be at all efficient, or even to compile (but it should give you the basic idea) - spoilers!

    // A utility function to represent the result of appending to a vector,
    // as a new vector (without affecting the previous one).
    template <typename T>
    vector<T> operator<<(vector<T> copy, T to_append) {
        // We passed by value to get a copy implicitly.
        copy.push_back(to_append);
        return copy;
    }
    
    // A utility function to append one vector to another.
    template <typename T>
    vector<T>& operator+=(vector<T>& original, const vector<T>& to_append) {
        // 'copy' is in namespace std:: and defined in <algorithm>.
        // 'back_inserter' is in namespace std:: and defined in <iterator>.
        copy(to_append.begin(), to_append.end(), back_inserter(original));
        return original;
    }
    
    vector<vector<int> > partitions(int remaining, int limit, vector<int> prefix) {
        // Finds the partitions of some larger number which start with the
        // numbers in 'prefix', such that the rest of the "chunks" sum to
        // 'remaining' and are all no larger than 'limit'.
    
        // 'max' is in namespace std:: and defined in <algorithm>. We restrict
        // the 'limit' to be no more than 'remaining'.
        limit = max(remaining, limit);
    
        vector<vector<int> > result;
    
        // Base case. 
        if (remaining == 1) {
            return result << (prefix << 1); // note the parentheses are required!
        }
    
        for (int i = limit; i > 0; --i) {
            result += partitions(remaining - i, i, prefix << i);
        }
    
        return result;
    }
    
    0 讨论(0)
提交回复
热议问题