给定四个正整数N、K、L和R ,任务是将 N 拆分为[L, R]范围内 K 个数字的总和。
注意:由于方式的数量可能非常大。输出答案模1000000007 。
例子:
Input : N = 12, K = 3, L = 1, R = 5
Output : 10
{2, 5, 5}
{3, 4, 5}
{3, 5, 4}
{4, 3, 5}
{4, 4, 4}
{4, 5, 3}
{5, 2, 5}
{5, 3, 4}
{5, 4, 3}
{5, 5, 2}
Input : N = 23, K = 4, L = 2, R = 10
Output : 480
天真的方法
我们可以使用递归来解决这个问题。在递归的每一步尝试使一组大小为 L 到 R 所有
递归中有两个参数会发生变化:
- pos – 组号
- left – 剩下多少 N 需要分配
下面是上述方法的实现:
C++
// C++ implementation to count the
// number of ways to divide N in K
// groups such that each group
// has elements in range [L, R]
#include
using namespace std;
const int mod = 1000000007;
// Function to count the number
// of ways to divide the number N
// in K groups such that each group
// has number of elements in range [L, R]
int calculate(int pos, int left,
int k, int L, int R)
{
// 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 = L; i <= R; i++) {
if (i > left)
break;
answer = (answer + calculate(pos + 1,
left - i, k, L, R))
% mod;
}
return answer;
}
// Function to count the number of
// ways to divide the number N
int countWaystoDivide(int n, int k,
int L, int R)
{
return calculate(0, n, k, L, R);
}
// Driver Code
int main()
{
int N = 12;
int K = 3;
int L = 1;
int R = 5;
cout << countWaystoDivide(N, K, L, R);
return 0;
}
Java
// Java implementation to count the
// number of ways to divide N in K
// groups such that each group
// has elements in range [L, R]
class GFG{
static int mod = 1000000007;
// Function to count the number
// of ways to divide the number N
// in K groups such that each group
// has number of elements in range [L, R]
static int calculate(int pos, int left,
int k, int L, int R)
{
// 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 = L; i <= R; i++)
{
if (i > left)
break;
answer = ((answer +
calculate(pos + 1,left - i,
k, L, R)) % mod);
}
return answer;
}
// Function to count the number of
// ways to divide the number N
static int countWaystoDivide(int n, int k,
int L, int R)
{
return calculate(0, n, k, L, R);
}
// Driver Code
public static void main(String[] args)
{
int N = 12;
int K = 3;
int L = 1;
int R = 5;
System.out.print(countWaystoDivide(N, K, L, R));
}
}
// This code is contributed by Amit Katiyar
Python3
# Python3 implementation to count the
# number of ways to divide N in K
# groups such that each group
# has elements in range [L, R]
mod = 1000000007
# Function to count the number
# of ways to divide the number N
# in K groups such that each group
# has number of elements in range [L, R]
def calculate(pos, left, k, L, R):
# 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(L, R + 1):
if (i > left):
break
answer = (answer +
calculate(pos + 1,
left - i, k, L, R)) % mod
return answer
# Function to count the number of
# ways to divide the number N
def countWaystoDivide(n, k, L, R):
return calculate(0, n, k, L, R)
# Driver Code
N = 12
K = 3
L = 1
R = 5
print(countWaystoDivide(N, K, L, R))
# This code is contributed by divyamohan123
C#
// C# implementation to count the
// number of ways to divide N in K
// groups such that each group
// has elements in range [L, R]
using System;
class GFG{
static int mod = 1000000007;
// Function to count the number
// of ways to divide the number N
// in K groups such that each group
// has number of elements in range [L, R]
static int calculate(int pos, int left,
int k, int L, int R)
{
// 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 = L; i <= R; i++)
{
if (i > left)
break;
answer = ((answer +
calculate(pos + 1,left - i,
k, L, R)) % mod);
}
return answer;
}
// Function to count the number of
// ways to divide the number N
static int countWaystoDivide(int n, int k,
int L, int R)
{
return calculate(0, n, k, L, R);
}
// Driver Code
public static void Main(String[] args)
{
int N = 12;
int K = 3;
int L = 1;
int R = 5;
Console.Write(countWaystoDivide(N, K, L, R));
}
}
// This code is contributed by Amit Katiyar
Javascript
C++
// C++ implementation to count the
// number of ways to divide N in K
// groups such that each group
// has elements in range [L, R]
#include
using namespace std;
const int mod = 1000000007;
// DP Table
int dp[1000][1000];
// Function to count the number
// of ways to divide the number N
// in K groups such that each group
// has number of elements in range [L, R]
int calculate(int pos, int left,
int k, int L, int R)
{
// 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][left] != -1)
return dp[pos][left];
int answer = 0;
// put all possible values
// greater equal to prev
for (int i = L; i <= R; i++) {
if (i > left)
break;
answer = (answer + calculate(pos + 1,
left - i, k, L, R))
% mod;
}
return dp[pos][left] = answer;
}
// Function to count the number of
// ways to divide the number N
int countWaystoDivide(int n, int k,
int L, int R)
{
// Initialize DP Table as -1
memset(dp, -1, sizeof(dp));
return calculate(0, n, k, L, R);
}
// Driver Code
int main()
{
int N = 12;
int K = 3;
int L = 1;
int R = 5;
cout << countWaystoDivide(N, K, L, R);
return 0;
}
Java
// Java implementation to count the
// number of ways to divide N in K
// groups such that each group
// has elements in range [L, R]
class GFG{
static int mod = 1000000007;
// DP Table
static int [][]dp = new int[1000][1000];
// Function to count the number
// of ways to divide the number N
// in K groups such that each group
// has number of elements in range [L, R]
static int calculate(int pos, int left,
int k, int L, int R)
{
// 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][left] != -1)
return dp[pos][left];
int answer = 0;
// Put all possible values
// greater equal to prev
for(int i = L; i <= R; i++)
{
if (i > left)
break;
answer = (answer + calculate(pos + 1, left - i,
k, L, R)) % mod;
}
return dp[pos][left] = answer;
}
// Function to count the number of
// ways to divide the number N
static int countWaystoDivide(int n, int k,
int L, int R)
{
// Initialize DP Table as -1
for(int i = 0; i < 1000; i++)
{
for(int j = 0; j < 1000; j++)
{
dp[i][j] = -1;
}
}
return calculate(0, n, k, L, R);
}
// Driver Code
public static void main(String[] args)
{
int N = 12;
int K = 3;
int L = 1;
int R = 5;
System.out.print(countWaystoDivide(N, K, L, R));
}
}
// This code is contributed by 29AjayKumar
Python3
# Python3 implementation to count the
# number of ways to divide N in K
# groups such that each group
# has elements in range [L, R]
mod = 1000000007
# DP Table
dp = [[-1 for j in range(1000)]
for i in range(1000)]
# Function to count the number
# of ways to divide the number N
# in K groups such that each group
# has number of elements in range [L, R]
def calculate(pos, left, k, L, R):
# 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][left] != -1):
return dp[pos][left]
answer = 0
# put all possible values
# greater equal to prev
for i in range(L, R + 1):
if (i > left):
break
answer = (answer +
calculate(pos + 1,
left - i,
k, L, R)) % mod
dp[pos][left] = answer
return answer
# Function to count the number of
# ways to divide the number N
def countWaystoDivide(n, k, L, R):
return calculate(0, n, k, L, R)
# Driver code
if __name__=="__main__":
N = 12
K = 3
L = 1
R = 5
print(countWaystoDivide(N, K, L, R))
# This code is contributed by rutvik_56
C#
// C# implementation to count the
// number of ways to divide N in K
// groups such that each group
// has elements in range [L, R]
using System;
class GFG{
static int mod = 1000000007;
// DP Table
static int [,]dp = new int[1000, 1000];
// Function to count the number
// of ways to divide the number N
// in K groups such that each group
// has number of elements in range [L, R]
static int calculate(int pos, int left,
int k, int L, int R)
{
// 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, left] != -1)
return dp[pos, left];
int answer = 0;
// Put all possible values
// greater equal to prev
for(int i = L; i <= R; i++)
{
if (i > left)
break;
answer = (answer + calculate(pos + 1, left - i,
k, L, R)) % mod;
}
return dp[pos, left] = answer;
}
// Function to count the number of
// ways to divide the number N
static int countWaystoDivide(int n, int k,
int L, int R)
{
// Initialize DP Table as -1
for(int i = 0; i < 1000; i++)
{
for(int j = 0; j < 1000; j++)
{
dp[i, j] = -1;
}
}
return calculate(0, n, k, L, R);
}
// Driver Code
public static void Main()
{
int N = 12;
int K = 3;
int L = 1;
int R = 5;
Console.Write(countWaystoDivide(N, K, L, R));
}
}
// This code is contributed by Code_Mech
Javascript
输出:
10
时间复杂度: O(N K ) 。
高效方法:在前面的方法中,我们可以看到我们在重复解决子问题,即它遵循重叠子问题的性质。所以我们可以使用 DP 表记住相同的内容。
下面是上述方法的实现:
C++
// C++ implementation to count the
// number of ways to divide N in K
// groups such that each group
// has elements in range [L, R]
#include
using namespace std;
const int mod = 1000000007;
// DP Table
int dp[1000][1000];
// Function to count the number
// of ways to divide the number N
// in K groups such that each group
// has number of elements in range [L, R]
int calculate(int pos, int left,
int k, int L, int R)
{
// 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][left] != -1)
return dp[pos][left];
int answer = 0;
// put all possible values
// greater equal to prev
for (int i = L; i <= R; i++) {
if (i > left)
break;
answer = (answer + calculate(pos + 1,
left - i, k, L, R))
% mod;
}
return dp[pos][left] = answer;
}
// Function to count the number of
// ways to divide the number N
int countWaystoDivide(int n, int k,
int L, int R)
{
// Initialize DP Table as -1
memset(dp, -1, sizeof(dp));
return calculate(0, n, k, L, R);
}
// Driver Code
int main()
{
int N = 12;
int K = 3;
int L = 1;
int R = 5;
cout << countWaystoDivide(N, K, L, R);
return 0;
}
Java
// Java implementation to count the
// number of ways to divide N in K
// groups such that each group
// has elements in range [L, R]
class GFG{
static int mod = 1000000007;
// DP Table
static int [][]dp = new int[1000][1000];
// Function to count the number
// of ways to divide the number N
// in K groups such that each group
// has number of elements in range [L, R]
static int calculate(int pos, int left,
int k, int L, int R)
{
// 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][left] != -1)
return dp[pos][left];
int answer = 0;
// Put all possible values
// greater equal to prev
for(int i = L; i <= R; i++)
{
if (i > left)
break;
answer = (answer + calculate(pos + 1, left - i,
k, L, R)) % mod;
}
return dp[pos][left] = answer;
}
// Function to count the number of
// ways to divide the number N
static int countWaystoDivide(int n, int k,
int L, int R)
{
// Initialize DP Table as -1
for(int i = 0; i < 1000; i++)
{
for(int j = 0; j < 1000; j++)
{
dp[i][j] = -1;
}
}
return calculate(0, n, k, L, R);
}
// Driver Code
public static void main(String[] args)
{
int N = 12;
int K = 3;
int L = 1;
int R = 5;
System.out.print(countWaystoDivide(N, K, L, R));
}
}
// This code is contributed by 29AjayKumar
蟒蛇3
# Python3 implementation to count the
# number of ways to divide N in K
# groups such that each group
# has elements in range [L, R]
mod = 1000000007
# DP Table
dp = [[-1 for j in range(1000)]
for i in range(1000)]
# Function to count the number
# of ways to divide the number N
# in K groups such that each group
# has number of elements in range [L, R]
def calculate(pos, left, k, L, R):
# 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][left] != -1):
return dp[pos][left]
answer = 0
# put all possible values
# greater equal to prev
for i in range(L, R + 1):
if (i > left):
break
answer = (answer +
calculate(pos + 1,
left - i,
k, L, R)) % mod
dp[pos][left] = answer
return answer
# Function to count the number of
# ways to divide the number N
def countWaystoDivide(n, k, L, R):
return calculate(0, n, k, L, R)
# Driver code
if __name__=="__main__":
N = 12
K = 3
L = 1
R = 5
print(countWaystoDivide(N, K, L, R))
# This code is contributed by rutvik_56
C#
// C# implementation to count the
// number of ways to divide N in K
// groups such that each group
// has elements in range [L, R]
using System;
class GFG{
static int mod = 1000000007;
// DP Table
static int [,]dp = new int[1000, 1000];
// Function to count the number
// of ways to divide the number N
// in K groups such that each group
// has number of elements in range [L, R]
static int calculate(int pos, int left,
int k, int L, int R)
{
// 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, left] != -1)
return dp[pos, left];
int answer = 0;
// Put all possible values
// greater equal to prev
for(int i = L; i <= R; i++)
{
if (i > left)
break;
answer = (answer + calculate(pos + 1, left - i,
k, L, R)) % mod;
}
return dp[pos, left] = answer;
}
// Function to count the number of
// ways to divide the number N
static int countWaystoDivide(int n, int k,
int L, int R)
{
// Initialize DP Table as -1
for(int i = 0; i < 1000; i++)
{
for(int j = 0; j < 1000; j++)
{
dp[i, j] = -1;
}
}
return calculate(0, n, k, L, R);
}
// Driver Code
public static void Main()
{
int N = 12;
int K = 3;
int L = 1;
int R = 5;
Console.Write(countWaystoDivide(N, K, L, R));
}
}
// This code is contributed by Code_Mech
Javascript
输出:
10
时间复杂度: O(N 2 ) 。