📌  相关文章
📜  计算将N逐步分为k组的方式的数量

📅  最后修改于: 2021-04-26 08:07:48             🧑  作者: Mango

给定两个整数NK ,任务是计算将N划分为K个正整数组的方式数,以使它们的总和为N,并且组中元素的数量遵循非降序(即,group [i] <=组[i + 1])。
例子:

天真的方法:我们可以使用递归解决此问题。在递归的每个步骤中,将所有值都大于等于先前计算的值。
下面是上述方法的实现:

C++
// C++ implementation to count the
// number of ways to divide N in
// groups such that each group
// has K number of elements
 
#include 
 
using namespace std;
 
// Function to count the number
// of ways to divide the number N
// in groups such that each group
// has K number of elements
int calculate(int pos, int prev,
                 int left, int k)
{
    // Base Case
    if (pos == k) {
        if (left == 0)
            return 1;
        else
            return 0;
    }
 
    // if N is divides completely
    // into less than k groups
    if (left == 0)
        return 0;
 
    int answer = 0;
     
    // put all possible values
    // greater equal to prev
    for (int i = prev; i <= left; i++) {
        answer += calculate(pos + 1, i,
                          left - i, k);
    }
    return answer;
}
 
// Function to count the number of
// ways to divide the number N
int countWaystoDivide(int n, int k)
{
    return calculate(0, 1, n, k);
}
 
// Driver Code
int main()
{
    int N = 8;
    int K = 4;
 
    cout << countWaystoDivide(N, K);
    return 0;
}


Java
// Java implementation to count the
// number of ways to divide N in
// groups such that each group
// has K number of elements
import java.util.*;
class GFG{
 
// Function to count the number
// of ways to divide the number N
// in groups such that each group
// has K number of elements
static int calculate(int pos, int prev,
                     int left, int k)
{
     
    // Base Case
    if (pos == k)
    {
        if (left == 0)
            return 1;
        else
            return 0;
    }
 
    // If N is divides completely
    // into less than k groups
    if (left == 0)
        return 0;
 
    int answer = 0;
     
    // Put all possible values
    // greater equal to prev
    for(int i = prev; i <= left; i++)
    {
       answer += calculate(pos + 1, i,
                           left - i, k);
    }
    return answer;
}
 
// Function to count the number of
// ways to divide the number N
static int countWaystoDivide(int n, int k)
{
    return calculate(0, 1, n, k);
}
 
// Driver Code
public static void main(String[] args)
{
    int N = 8;
    int K = 4;
 
    System.out.print(countWaystoDivide(N, K));
}
}
 
// This code is contributed by Rajput-Ji


Python3
# Python3 implementation to count the
# number of ways to divide N in
# groups such that each group
# has K number of elements
 
# Function to count the number
# of ways to divide the number N
# in groups such that each group
# has K number of elements
def calculate(pos, prev, left, k):
     
    # Base Case
    if (pos == k):
        if (left == 0):
            return 1;
        else:
            return 0;
 
    # If N is divides completely
    # into less than k groups
    if (left == 0):
        return 0;
 
    answer = 0;
 
    # Put all possible values
    # greater equal to prev
    for i in range(prev, left + 1):
        answer += calculate(pos + 1, i,
                           left - i, k);
 
    return answer;
 
# Function to count the number of
# ways to divide the number N
def countWaystoDivide(n, k):
     
    return calculate(0, 1, n, k);
 
# Driver Code
if __name__ == '__main__':
     
    N = 8;
    K = 4;
 
    print(countWaystoDivide(N, K));
 
# This code is contributed by 29AjayKumar


C#
// C# implementation to count the
// number of ways to divide N in
// groups such that each group
// has K number of elements
using System;
 
class GFG{
 
// Function to count the number
// of ways to divide the number N
// in groups such that each group
// has K number of elements
static int calculate(int pos, int prev,
                     int left, int k)
{
     
    // Base Case
    if (pos == k)
    {
        if (left == 0)
            return 1;
        else
            return 0;
    }
 
    // If N is divides completely
    // into less than k groups
    if (left == 0)
        return 0;
 
    int answer = 0;
     
    // Put all possible values
    // greater equal to prev
    for(int i = prev; i <= left; i++)
    {
       answer += calculate(pos + 1, i,
                           left - i, k);
    }
    return answer;
}
 
// Function to count the number of
// ways to divide the number N
static int countWaystoDivide(int n, int k)
{
    return calculate(0, 1, n, k);
}
 
// Driver Code
public static void Main(String[] args)
{
    int N = 8;
    int K = 4;
 
    Console.Write(countWaystoDivide(N, K));
}
}
 
// This code is contributed by Rajput-Ji


C++
// C++ implementation to count the
// number of ways to divide N in
// groups such that each group
// has K number of elements
 
#include 
 
using namespace std;
 
// DP Table
int dp[500][500][500];
 
// Function to count the number
// of ways to divide the number N
// in groups such that each group
// has K number of elements
int calculate(int pos, int prev,
                int left, int k)
{
    // Base Case
    if (pos == k) {
        if (left == 0)
            return 1;
        else
            return 0;
    }
    // if N is divides completely
    // into less than k groups
    if (left == 0)
        return 0;
 
    // If the subproblem has been
    // solved, use the value
    if (dp[pos][prev][left] != -1)
        return dp[pos][prev][left];
 
    int answer = 0;
    // put all possible values
    // greater equal to prev
    for (int i = prev; i <= left; i++) {
        answer += calculate(pos + 1, i,
                           left - i, k);
    }
 
    return dp[pos][prev][left] = answer;
}
 
// Function to count the number of
// ways to divide the number N in groups
int countWaystoDivide(int n, int k)
{
    // Intialize DP Table as -1
    memset(dp, -1, sizeof(dp));
 
    return calculate(0, 1, n, k);
}
 
// Driver Code
int main()
{
    int N = 8;
    int K = 4;
 
    cout << countWaystoDivide(N, K);
    return 0;
}


Java
// Java implementation to count the
// number of ways to divide N in
// groups such that each group
// has K number of elements
import java.util.*;
class GFG{
  
// DP Table
static int [][][]dp = new int[500][500][500];
  
// Function to count the number
// of ways to divide the number N
// in groups such that each group
// has K number of elements
static int calculate(int pos, int prev,
                     int left, int k)
{
    // Base Case
    if (pos == k)
    {
        if (left == 0)
            return 1;
        else
            return 0;
    }
   
    // if N is divides completely
    // into less than k groups
    if (left == 0)
        return 0;
  
    // If the subproblem has been
    // solved, use the value
    if (dp[pos][prev][left] != -1)
        return dp[pos][prev][left];
  
    int answer = 0;
   
    // put all possible values
    // greater equal to prev
    for (int i = prev; i <= left; i++)
    {
        answer += calculate(pos + 1, i,
                           left - i, k);
    }
  
    return dp[pos][prev][left] = answer;
}
  
// Function to count the number of
// ways to divide the number N in groups
static int countWaystoDivide(int n, int k)
{
    // Intialize DP Table as -1
        for (int i = 0; i < 500; i++)
        {
            for (int j = 0; j < 500; j++)
            {
                for (int l = 0; l < 500; l++)
                    dp[i][j][l] = -1;
            }
        }
  
    return calculate(0, 1, n, k);
}
  
// Driver Code
public static void main(String[] args)
{
    int N = 8;
    int K = 4;
  
    System.out.print(countWaystoDivide(N, K));
}
}
 
// This code is contributed by Rajput-Ji


Python3
# Python3 implementation to count the
# number of ways to divide N in
# groups such that each group
# has K number of elements
  
# DP Table
dp = [[[0 for i in range(50)]
             for j in range(50)]
          for j in range(50)]
 
# Function to count the number
# of ways to divide the number N
# in groups such that each group
# has K number of elements
def calculate(pos, prev, left, k):
    
    # Base Case
    if (pos == k):
        if (left == 0):
            return 1;
        else:
            return 0;
  
    # if N is divides completely
    # into less than k groups
    if (left == 0):
        return 0;
  
    # If the subproblem has been
    # solved, use the value
    if (dp[pos][prev][left] != -1):
        return dp[pos][prev][left];
  
    answer = 0;
  
    # put all possible values
    # greater equal to prev
    for i in range(prev,left+1):
        answer += calculate(pos + 1, i,
                            left - i, k);
    dp[pos][prev][left] = answer;
    return dp[pos][prev][left];
  
# Function to count the number of
# ways to divide the number N in groups
def countWaystoDivide(n, k):
   
    # Intialize DP Table as -1
    for i in range(50):
        for j in range(50):
            for l in range(50):
                dp[i][j][l] = -1;
  
    return calculate(0, 1, n, k);
  
# Driver Code
if __name__ == '__main__':
    N = 8;
    K = 4;
  
    print(countWaystoDivide(N, K));
  
# This code is contributed by Rajput-Ji


C#
// C# implementation to count the
// number of ways to divide N in
// groups such that each group
// has K number of elements
using System;
class GFG{
  
// DP Table
static int [,,]dp = new int[50, 50, 50];
  
// Function to count the number
// of ways to divide the number N
// in groups such that each group
// has K number of elements
static int calculate(int pos, int prev,
                     int left, int k)
{
    // Base Case
    if (pos == k)
    {
        if (left == 0)
            return 1;
        else
            return 0;
    }
   
    // if N is divides completely
    // into less than k groups
    if (left == 0)
        return 0;
  
    // If the subproblem has been
    // solved, use the value
    if (dp[pos, prev, left] != -1)
        return dp[pos, prev, left];
  
    int answer = 0;
   
    // put all possible values
    // greater equal to prev
    for (int i = prev; i <= left; i++)
    {
        answer += calculate(pos + 1, i,
                           left - i, k);
    }
  
    return dp[pos, prev, left] = answer;
}
  
// Function to count the number of
// ways to divide the number N in groups
static int countWaystoDivide(int n, int k)
{
    // Intialize DP Table as -1
        for (int i = 0; i < 50; i++)
        {
            for (int j = 0; j < 50; j++)
            {
                for (int l = 0; l < 50; l++)
                    dp[i, j, l] = -1;
            }
        }
  
    return calculate(0, 1, n, k);
}
  
// Driver Code
public static void Main(String[] args)
{
    int N = 8;
    int K = 4;
  
    Console.Write(countWaystoDivide(N, K));
}
}
 
// This code is contributed by gauravrajput1


输出:
5


时间复杂度: O(N K )
高效的方法:在以前的方法中,我们可以看到我们正在反复求解子问题,即它遵循“重叠子问题”的属性。因此,我们可以使用DP表记住相同的内容。
下面是上述方法的实现:

C++

// C++ implementation to count the
// number of ways to divide N in
// groups such that each group
// has K number of elements
 
#include 
 
using namespace std;
 
// DP Table
int dp[500][500][500];
 
// Function to count the number
// of ways to divide the number N
// in groups such that each group
// has K number of elements
int calculate(int pos, int prev,
                int left, int k)
{
    // Base Case
    if (pos == k) {
        if (left == 0)
            return 1;
        else
            return 0;
    }
    // if N is divides completely
    // into less than k groups
    if (left == 0)
        return 0;
 
    // If the subproblem has been
    // solved, use the value
    if (dp[pos][prev][left] != -1)
        return dp[pos][prev][left];
 
    int answer = 0;
    // put all possible values
    // greater equal to prev
    for (int i = prev; i <= left; i++) {
        answer += calculate(pos + 1, i,
                           left - i, k);
    }
 
    return dp[pos][prev][left] = answer;
}
 
// Function to count the number of
// ways to divide the number N in groups
int countWaystoDivide(int n, int k)
{
    // Intialize DP Table as -1
    memset(dp, -1, sizeof(dp));
 
    return calculate(0, 1, n, k);
}
 
// Driver Code
int main()
{
    int N = 8;
    int K = 4;
 
    cout << countWaystoDivide(N, K);
    return 0;
}

Java

// Java implementation to count the
// number of ways to divide N in
// groups such that each group
// has K number of elements
import java.util.*;
class GFG{
  
// DP Table
static int [][][]dp = new int[500][500][500];
  
// Function to count the number
// of ways to divide the number N
// in groups such that each group
// has K number of elements
static int calculate(int pos, int prev,
                     int left, int k)
{
    // Base Case
    if (pos == k)
    {
        if (left == 0)
            return 1;
        else
            return 0;
    }
   
    // if N is divides completely
    // into less than k groups
    if (left == 0)
        return 0;
  
    // If the subproblem has been
    // solved, use the value
    if (dp[pos][prev][left] != -1)
        return dp[pos][prev][left];
  
    int answer = 0;
   
    // put all possible values
    // greater equal to prev
    for (int i = prev; i <= left; i++)
    {
        answer += calculate(pos + 1, i,
                           left - i, k);
    }
  
    return dp[pos][prev][left] = answer;
}
  
// Function to count the number of
// ways to divide the number N in groups
static int countWaystoDivide(int n, int k)
{
    // Intialize DP Table as -1
        for (int i = 0; i < 500; i++)
        {
            for (int j = 0; j < 500; j++)
            {
                for (int l = 0; l < 500; l++)
                    dp[i][j][l] = -1;
            }
        }
  
    return calculate(0, 1, n, k);
}
  
// Driver Code
public static void main(String[] args)
{
    int N = 8;
    int K = 4;
  
    System.out.print(countWaystoDivide(N, K));
}
}
 
// This code is contributed by Rajput-Ji

Python3

# Python3 implementation to count the
# number of ways to divide N in
# groups such that each group
# has K number of elements
  
# DP Table
dp = [[[0 for i in range(50)]
             for j in range(50)]
          for j in range(50)]
 
# Function to count the number
# of ways to divide the number N
# in groups such that each group
# has K number of elements
def calculate(pos, prev, left, k):
    
    # Base Case
    if (pos == k):
        if (left == 0):
            return 1;
        else:
            return 0;
  
    # if N is divides completely
    # into less than k groups
    if (left == 0):
        return 0;
  
    # If the subproblem has been
    # solved, use the value
    if (dp[pos][prev][left] != -1):
        return dp[pos][prev][left];
  
    answer = 0;
  
    # put all possible values
    # greater equal to prev
    for i in range(prev,left+1):
        answer += calculate(pos + 1, i,
                            left - i, k);
    dp[pos][prev][left] = answer;
    return dp[pos][prev][left];
  
# Function to count the number of
# ways to divide the number N in groups
def countWaystoDivide(n, k):
   
    # Intialize DP Table as -1
    for i in range(50):
        for j in range(50):
            for l in range(50):
                dp[i][j][l] = -1;
  
    return calculate(0, 1, n, k);
  
# Driver Code
if __name__ == '__main__':
    N = 8;
    K = 4;
  
    print(countWaystoDivide(N, K));
  
# This code is contributed by Rajput-Ji

C#

// C# implementation to count the
// number of ways to divide N in
// groups such that each group
// has K number of elements
using System;
class GFG{
  
// DP Table
static int [,,]dp = new int[50, 50, 50];
  
// Function to count the number
// of ways to divide the number N
// in groups such that each group
// has K number of elements
static int calculate(int pos, int prev,
                     int left, int k)
{
    // Base Case
    if (pos == k)
    {
        if (left == 0)
            return 1;
        else
            return 0;
    }
   
    // if N is divides completely
    // into less than k groups
    if (left == 0)
        return 0;
  
    // If the subproblem has been
    // solved, use the value
    if (dp[pos, prev, left] != -1)
        return dp[pos, prev, left];
  
    int answer = 0;
   
    // put all possible values
    // greater equal to prev
    for (int i = prev; i <= left; i++)
    {
        answer += calculate(pos + 1, i,
                           left - i, k);
    }
  
    return dp[pos, prev, left] = answer;
}
  
// Function to count the number of
// ways to divide the number N in groups
static int countWaystoDivide(int n, int k)
{
    // Intialize DP Table as -1
        for (int i = 0; i < 50; i++)
        {
            for (int j = 0; j < 50; j++)
            {
                for (int l = 0; l < 50; l++)
                    dp[i, j, l] = -1;
            }
        }
  
    return calculate(0, 1, n, k);
}
  
// Driver Code
public static void Main(String[] args)
{
    int N = 8;
    int K = 4;
  
    Console.Write(countWaystoDivide(N, K));
}
}
 
// This code is contributed by gauravrajput1

输出:

5

时间复杂度: O(N 2 * K)