📌  相关文章
📜  在给定约束下由三组组成一个组的方法

📅  最后修改于: 2021-06-25 11:28:08             🧑  作者: Mango

给定三个数字(x,y和z),它们分别代表第一组,第二组和第三组的人数。我们可以通过从第一组,第二组和第三组中选择人员来形成组,以使以下条件不会无效。

  • 每个组中至少要选择一个人。
  • 从第一组中选出的人数必须至少比从第三组中选出的人数多一个。

任务是找到形成不同群体的方式。

例子:

可以使用组合方法解决该问题。需要填补三个职位(就不同群体的人而言)。第一个必须填充一个比第二个位置大一个或多个的数字。第三个可以填充任何数字。我们知道如果我们需要用N个人填补k个职位,那么做这件事的方法就是{N \choose K} 。因此,可以遵循以下步骤来解决上述问题。

  • 第二个职位可以由i = 1到i = y个人填补。
  • 第一个职位可以由j = i + 1到j = x个人填补。
  • 第三个位置可以填充任意数量的k = 1至k = z个人。
  • 因此,共同的事情是用k人填补第三位置。因此,我们可以将该部分视为通用的。
  • 运行两个循环(i和j)分别填充第二个位置和第一个位置。
  • 填补职位的方式有{y \choose i} * {x \choose j}
  • 在计算完所有方法以填补这两个位置后,我们可以简单地乘以{z \choose 1} + {z \choose 2} +… {z \choose z}因为那是两者的共同部分。

{N \choose K}可以使用动态编程预先计算以减少时间复杂度。该方法在这里讨论。

下面是上述方法的实现。

C++
// C++ program to find the number of
// ways to form the group of peopls
#include 
using namespace std;
  
int C[1000][1000];
  
// Function to pre-compute the
// Combination using DP
void binomialCoeff(int n)
{
    int i, j;
  
    // Calculate value of Binomial Coefficient
    // in bottom up manner
    for (i = 0; i <= n; i++) {
        for (j = 0; j <= i; j++) {
  
            // Base Cases
            if (j == 0 || j == i)
                C[i][j] = 1;
  
            // Calculate value using previously
            // stored values
            else
                C[i][j] = C[i - 1][j - 1] + C[i - 1][j];
        }
    }
  
    // return C[n][k];
}
  
// Function to find the number of ways
int numberOfWays(int x, int y, int z)
{
    // Function to pre-compute
    binomialCoeff(max(x, max(y, z)));
  
    // Sum the Zci
    int sum = 0;
    for (int i = 1; i <= z; i++) {
        sum = (sum + C[z][i]);
    }
  
    // Iterate for second position
    int sum1 = 0;
    for (int i = 1; i <= y; i++) {
  
        // Iterate for first position
        for (int j = i + 1; j <= x; j++) {
            sum1 = (sum1 + (C[y][i] * C[x][j]));
        }
    }
  
    // Multiply the common Combination value
    sum1 = (sum * sum1);
  
    return sum1;
}
  
// Driver Code
int main()
{
    int x = 3;
    int y = 2;
    int z = 1;
  
    cout << numberOfWays(x, y, z);
  
    return 0;
}


Java
// Java program to find the number of 
// ways to form the group of peopls 
class GFG
{
      
static int C[][] = new int [1000][1000]; 
  
// Function to pre-compute the 
// Combination using DP 
static void binomialCoeff(int n) 
{ 
    int i, j; 
  
    // Calculate value of Binomial Coefficient 
    // in bottom up manner 
    for (i = 0; i <= n; i++) 
    { 
        for (j = 0; j <= i; j++) 
        { 
  
            // Base Cases 
            if (j == 0 || j == i) 
                C[i][j] = 1; 
  
            // Calculate value using previously 
            // stored values 
            else
                C[i][j] = C[i - 1][j - 1] + C[i - 1][j]; 
        } 
    } 
  
    // return C[n][k]; 
} 
  
// Function to find the number of ways 
static int numberOfWays(int x, int y, int z) 
{ 
    // Function to pre-compute 
    binomialCoeff(Math.max(x, Math.max(y, z))); 
  
    // Sum the Zci 
    int sum = 0; 
    for (int i = 1; i <= z; i++) 
    { 
        sum = (sum + C[z][i]); 
    } 
  
    // Iterate for second position 
    int sum1 = 0; 
    for (int i = 1; i <= y; i++)
    { 
  
        // Iterate for first position 
        for (int j = i + 1; j <= x; j++)
        { 
            sum1 = (sum1 + (C[y][i] * C[x][j])); 
        } 
    } 
  
    // Multiply the common Combination value 
    sum1 = (sum * sum1); 
  
    return sum1; 
} 
  
// Driver Code 
public static void main(String args[]) 
{ 
    int x = 3; 
    int y = 2; 
    int z = 1; 
  
    System.out.println(numberOfWays(x, y, z)); 
} 
}
  
// This code is contributed by Arnab Kundu


Python3
# Python3 program to find the number of
# ways to form the group of peopls
C = [[0 for i in range(1000)] 
        for i in range(1000)]
  
# Function to pre-compute the
# Combination using DP
def binomialCoeff(n):
    i, j = 0, 0
  
    # Calculate value of Binomial Coefficient
    # in bottom up manner
    for i in range(n + 1):
        for j in range(i + 1):
  
            # Base Cases
            if (j == 0 or j == i):
                C[i][j] = 1
  
            # Calculate value using previously
            # stored values
            else:
                C[i][j] = C[i - 1][j - 1] + \
                          C[i - 1][j]
  
    # return C[n][k]
  
# Function to find the number of ways
def numberOfWays(x, y, z):
      
    # Function to pre-compute
    binomialCoeff(max(x, max(y, z)))
  
    # Sum the Zci
    sum = 0
    for i in range(1, z + 1):
        sum = (sum + C[z][i])
  
    # Iterate for second position
    sum1 = 0
    for i in range(1, y + 1):
  
        # Iterate for first position
        for j in range(i + 1, x + 1):
            sum1 = (sum1 + (C[y][i] * C[x][j]))
  
    # Multiply the common Combination value
    sum1 = (sum * sum1)
  
    return sum1
  
# Driver Code
x = 3
y = 2
z = 1
  
print(numberOfWays(x, y, z))
  
# This code is contributed by Mohit Kumar


C#
// C# program to find the number of 
// ways to form the group of peopls 
using System;
      
class GFG
{
      
static int [,]C = new int [1000,1000]; 
  
// Function to pre-compute the 
// Combination using DP 
static void binomialCoeff(int n) 
{ 
    int i, j; 
  
    // Calculate value of Binomial Coefficient 
    // in bottom up manner 
    for (i = 0; i <= n; i++) 
    { 
        for (j = 0; j <= i; j++) 
        { 
  
            // Base Cases 
            if (j == 0 || j == i) 
                C[i,j] = 1; 
  
            // Calculate value using previously 
            // stored values 
            else
                C[i,j] = C[i - 1,j - 1] + C[i - 1,j]; 
        } 
    } 
  
    // return C[n,k]; 
} 
  
// Function to find the number of ways 
static int numberOfWays(int x, int y, int z) 
{ 
    // Function to pre-compute 
    binomialCoeff(Math.Max(x, Math.Max(y, z))); 
  
    // Sum the Zci 
    int sum = 0; 
    for (int i = 1; i <= z; i++) 
    { 
        sum = (sum + C[z,i]); 
    } 
  
    // Iterate for second position 
    int sum1 = 0; 
    for (int i = 1; i <= y; i++)
    { 
  
        // Iterate for first position 
        for (int j = i + 1; j <= x; j++)
        { 
            sum1 = (sum1 + (C[y,i] * C[x,j])); 
        } 
    } 
  
    // Multiply the common Combination value 
    sum1 = (sum * sum1); 
  
    return sum1; 
} 
  
// Driver Code 
public static void Main(String []args) 
{ 
    int x = 3; 
    int y = 2; 
    int z = 1; 
  
    Console.WriteLine(numberOfWays(x, y, z)); 
} 
}
  
// This code is contributed by Rajput-Ji


输出:
9

时间复杂度: O(K * K),其中K是(x,y和z)的最大值。