给定三个整数N 、 P和K ,任务是找到将N分成K 个整数的方法总数,其总和为N ,其中每个整数≥ P 。
例子:
Input: K = 3, N = 8, P = 2
Output: 6
Explanation:
Six possible solutions are: {2, 2, 4}, {2, 3, 3}, {2, 4, 2}, {3, 2, 3}, {3, 3, 2}, {4, 2, 2}
Each of the above integers in all combinations are ≥ P(= 2) and sum of all the combinations is N(=8).
Input: K = 2, N = 7, P = 2
Output: 4
Explanation:
Four possible solutions are: {4, 3}, {3, 4}, {5, 2}, {2, 5}
Each of the above integers in all combinations are ≥ P(= 2) and sum of all the combinations is N(= 7).
朴素方法:最简单的方法是尝试总和为N的K 个整数的所有可能组合,并检查它们是否满足上述条件。有K个位置,每个位置可以放置N个整数。因此,要检查的组合总数为N K 。
时间复杂度: O(N K )
辅助空间: O(1)
高效的方法:为了优化上述方法,想法是使用本文中讨论的方法,并且上述给定的条件可以写成线性方程为:
To find the number of solutions for the equation X1 + X2 + X3 + … + XK = N where Xi ≥ P.
Assume Xi‘ = Xi – P.
Therefore, the equation reduces to:
X1‘ + X2‘ + X3‘ + … + XK‘ = N – K*P
根据上面的等式,给定的问题简化为找到将N – K * P拆分为K 个整数的方法总数。打印上面找到的方法总数作为必需的答案。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function that finds the value of
// the Binomial Coefficient C(n, k)
int binomialCoeff(int n, int k)
{
int C[n + 1][k + 1];
int i, j;
// Stores the value of Binomial
// Coefficient in bottom up manner
for (i = 0; i <= n; i++) {
for (j = 0; j <= min(i, k); j++) {
// Base Case
if (j == 0 || j == i)
C[i][j] = 1;
// Find the value using
// previously stored values
else
C[i][j] = C[i - 1][j - 1]
+ C[i - 1][j];
}
}
// Return the value of C(N, K)
return C[n][k];
}
// Function that count the number of
// ways to divide N into K integers
// >= P such that their sum is N
int waysToSplitN(int k, int n, int P)
{
// Update the value of N
int new_N = n - k * P;
// Find the binomial coefficient
// recursively
return binomialCoeff(new_N + k - 1,
new_N);
}
// Driver Code
int main()
{
// Given K, N, and P
int K = 3, N = 8, P = 2;
cout << waysToSplitN(K, N, P);
return 0;
}
Java
// Java program for
// the above approach
import java.util.*;
class GFG{
// Function that finds the value of
// the Binomial Coefficient C(n, k)
static int binomialCoeff(int n, int k)
{
int [][]C = new int[n + 1][k + 1];
int i, j;
// Stores the value of Binomial
// Coefficient in bottom up manner
for (i = 0; i <= n; i++)
{
for (j = 0; j <= Math.min(i, k); j++)
{
// Base Case
if (j == 0 || j == i)
C[i][j] = 1;
// Find the value using
// previously stored values
else
C[i][j] = C[i - 1][j - 1] +
C[i - 1][j];
}
}
// Return the value of C(N, K)
return C[n][k];
}
// Function that count the number of
// ways to divide N into K integers
// >= P such that their sum is N
static int waysToSplitN(int k,
int n, int P)
{
// Update the value of N
int new_N = n - k * P;
// Find the binomial coefficient
// recursively
return binomialCoeff(new_N + k - 1,
new_N);
}
// Driver Code
public static void main(String[] args)
{
// Given K, N, and P
int K = 3, N = 8, P = 2;
System.out.print(waysToSplitN(K, N, P));
}
}
// This code is contributed by 29AjayKumar
Python3
# Python3 program for the above approach
# Function that finds the value of
# the Binomial Coefficient C(n, k)
def binomialCoeff(n, k):
C = [[0 for x in range(k + 1)]
for y in range(n + 1)]
# Stores the value of Binomial
# Coefficient in bottom up manner
for i in range(n + 1):
for j in range(min(i, k) + 1):
# Base Case
if(j == 0 or j == i):
C[i][j] = 1
# Find the value using
# previously stored values
else:
C[i][j] = (C[i - 1][j - 1] +
C[i - 1][j])
# Return the value of C(N, K)
return C[n][k]
# Function that count the number of
# ways to divide N into K integers
# >= P such that their sum is N
def waysToSplitN(k, n, P):
# Update the value of N
new_N = n - k * P
# Find the binomial coefficient
# recursively
return binomialCoeff(new_N + k - 1,
new_N)
# Driver Code
# Given K, N, and P
K = 3
N = 8
P = 2
print(waysToSplitN(K, N, P))
# This code is contributed by Shivam Singh
C#
// C# program for the above approach
using System;
class GFG{
// Function that finds the value of
// the Binomial Coefficient C(n, k)
static int binomialCoeff(int n, int k)
{
int [,] C = new int[n + 1, k + 1];
int i, j;
// Stores the value of Binomial
// Coefficient in bottom up manner
for(i = 0; i <= n; i++)
{
for(j = 0; j <= Math.Min(i, k); j++)
{
// Base Case
if (j == 0 || j == i)
C[i, j] = 1;
// Find the value using
// previously stored values
else
C[i, j] = C[i - 1, j - 1] +
C[i - 1, j];
}
}
// Return the value of C(N, K)
return C[n, k];
}
// Function that count the number of
// ways to divide N into K integers
// >= P such that their sum is N
static int waysToSplitN(int k, int n,
int P)
{
// Update the value of N
int new_N = n - k * P;
// Find the binomial coefficient
// recursively
return binomialCoeff(new_N + k - 1,
new_N);
}
// Driver Code
public static void Main()
{
// Given K, N, and P
int K = 3, N = 8, P = 2;
Console.Write(waysToSplitN(K, N, P));
}
}
// This code is contributed by sanjoy_62
Javascript
6
时间复杂度: O(N 2 )
辅助空间: O(N 2 )
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。