给定两个整数N和K ,任务是计算将N划分为K个正整数组的方式数,以使它们的总和为N,并且组中元素的数量遵循非降序(即,group [i] <=组[i + 1])。
例子:
Input: N = 8, K = 4
Output: 5
Explanation:
Their are 5 groups such that their sum is 8 and the number of positive integers in each group is 4.
[1, 1, 1, 5], [1, 1, 2, 4], [1, 1, 3, 3], [1, 2, 2, 3], [2, 2, 2, 2]
Input: N = 24, K = 5
Output: 164
Explanation:
There are 164 such groups such that their sum is 24 and number of positive integers in each group is 5
天真的方法:我们可以使用递归解决此问题。在递归的每个步骤中,将所有值都大于等于先前计算的值。
下面是上述方法的实现:
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)