📜  在给定约束下排列N个项目的方式数

📅  最后修改于: 2021-04-29 04:02:50             🧑  作者: Mango

我们给了N个项目,总共有K种不同的颜色。相同颜色的项目是无法区分的,并且颜色可以从1到K进行编号,每种颜色的项目计数也指定为k1,k2等。现在,对于所有可能的颜色,我们需要在颜色i的最后一项位于颜色的最后一项(i + 1)之前的约束下,逐一排列这些项。我们的目标是找出实现此目标的方法。

例子:

Input : N = 3        
        k1 = 1    k2 = 2
Output : 2
Explanation :
Possible ways to arrange are,
k1, k2, k2
k2, k1, k2 

Input : N = 4        
        k1 = 2    k2 = 2
Output : 3
Explanation :
Possible ways to arrange are,
k1, k2, k1, k2
k1, k1, k2, k2
k2, k1, k1, k2 

我们可以使用动态编程解决此问题。让dp [i]存储排列第i个有色项目的方式的数量。对于一种颜色的项目,答案将是一个,因为只有一种方法。现在,假设所有项目都在一个序列中。现在,要从dp [i]转到dp [i + 1],我们需要在末尾至少放置一种颜色(i + 1),但其他颜色(i + 1)可以放序列中的任何地方。排列颜色(i + 1)项的方式是(k1 + k2 .. + ki + k(i + 1)– 1)超过(k(i + 1)– 1)的组合,可以是表示为(k1 + k2 .. + ki + k(i + 1)– 1)C(k(i + 1)– 1)。在此表达式中我们减去了一个,因为我们需要在最后放置一个项目。
在下面的代码中,首先我们已经计算了组合值,您可以从此处了解更多信息。之后,我们遍历所有不同的颜色,并使用上述关系式计算出最终值。

C++
// C++ program to find number of ways to arrange
// items under given constraint
#include 
using namespace std;
  
// method returns number of ways with which items 
// can be arranged
int waysToArrange(int N, int K, int k[])
{
    int C[N + 1][N + 1];
    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]);
        }
    }
  
    // declare dp array to store result up to ith 
    // colored item
    int dp[K];
  
    // variable to keep track of count of items 
    // considered till now
    int count = 0;
  
    dp[0] = 1;
  
    // loop over all different colors
    for (int i = 0; i < K; i++) {
  
        // populate next value using current value 
        // and stated relation
        dp[i + 1] = (dp[i] * C[count + k[i] - 1][k[i] - 1]);
        count += k[i];
    }
  
    // return value stored at last index
    return dp[K];
}
  
// Driver code to test above methods
int main()
{
    int N = 4;
    int k[] = { 2, 2 };
  
    int K = sizeof(k) / sizeof(int);
    cout << waysToArrange(N, K, k) << endl;
    return 0;
}


Java
// Java program to find number of ways to arrange 
// items under given constraint 
class GFG 
{
  
    // method returns number of ways with which items 
    // can be arranged 
    static int waysToArrange(int N, int K, int[] k) 
    {
        int[][] C = new int[N + 1][N + 1];
        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]);
                }
            }
        }
  
        // declare dp array to store result up to ith 
        // colored item 
        int[] dp = new int[K + 1];
  
        // variable to keep track of count of items 
        // considered till now 
        int count = 0;
  
        dp[0] = 1;
  
        // loop over all different colors 
        for (i = 0; i < K; i++) 
        {
  
            // populate next value using current value 
            // and stated relation 
            dp[i + 1] = (dp[i] * C[count + k[i] - 1][k[i] - 1]);
            count += k[i];
        }
  
        // return value stored at last index 
        return dp[K];
    }
  
    // Driver code 
    public static void main(String[] args) 
    {
        int N = 4;
        int[] k = new int[]{2, 2};
        int K = k.length;
        System.out.println(waysToArrange(N, K, k));
    }
}
  
// This code has been contributed by 29AjayKumar


Python3
# Python3 program to find number of ways 
# to arrange items under given constraint
import numpy as np
  
# method returns number of ways with 
# which items can be arranged
def waysToArrange(N, K, k) :
  
    C = np.zeros((N + 1, N + 1))
  
    # 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])
  
    # declare dp array to store result 
    # up to ith colored item
    dp = np.zeros((K + 1))
  
    # variable to keep track of count 
    # of items considered till now
    count = 0
  
    dp[0] = 1
  
    # loop over all different colors
    for i in range(K) :
  
        # populate next value using current 
        # value and stated relation
        dp[i + 1] = (dp[i] * C[count + k[i] - 1][k[i] - 1])
        count += k[i]
      
    # return value stored at last index
    return dp[K]
  
# Driver code
if __name__ == "__main__" :
  
    N = 4
    k = [ 2, 2 ]
  
    K = len(k)
    print(int(waysToArrange(N, K, k)))
  
# This code is contributed by Ryuga


C#
// C# program to find number of ways to arrange 
// items under given constraint 
using System; 
  
class GFG 
{ 
    // method returns number of ways with which items 
    // can be arranged 
    static int waysToArrange(int N, int K, int[] k) 
    { 
        int[,] C = new int[N + 1, N + 1]; 
        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]); 
            } 
        } 
      
        // declare dp array to store result up to ith 
        // colored item 
        int[] dp = new int[K + 1]; 
      
        // variable to keep track of count of items 
        // considered till now 
        int count = 0; 
      
        dp[0] = 1; 
      
        // loop over all different colors 
        for (i = 0; i < K; i++) { 
      
            // populate next value using current value 
            // and stated relation 
            dp[i + 1] = (dp[i] * C[count + k[i] - 1, k[i] - 1]); 
            count += k[i]; 
        } 
      
        // return value stored at last index 
        return dp[K]; 
    } 
      
    // Driver code  
    static void Main() 
    { 
        int N = 4; 
        int[] k = new int[]{ 2, 2 }; 
        int K = k.Length; 
        Console.Write(waysToArrange(N, K, k)); 
    }
}
  
// This code is contributed by DrRoot_


PHP


输出:

3