给定一个表示红色和蓝色糖果数量的整数N和一个大小为N * N的矩阵mat[][] ,其中mat[i][j] = 1表示第i个红色糖果和第j个之间存在一对蓝色糖果,任务是找到选择N对糖果的方法的数量,使得每对包含不同颜色的不同糖果。
例子:
Input: N = 2, mat[][] = { { 1, 1 }, { 1, 1 } }
Output: 2
Explanation:
Possible ways to select N (= 2) pairs of candies are { { (1, 1), (2, 2) }, { (1, 2), (2, 1) } }.
Therefore, the required output is 2.
Input: N = 3, mat[][] = { { 0, 1, 1 }, { 1, 0, 1 }, { 1, 1, 1 } }
Output: 3
Explanation:
Possible ways to select N (= 3) pairs of candies are: { { (1, 2), (2, 1), (3, 3) }, { (1, 2), (2, 3), (3, 1) }, { (1, 3), (2, 1), (3, 2) } }
Therefore, the required output is 2.
朴素方法:解决此问题的最简单方法是生成包含不同颜色的不同糖果的N对的所有可能排列。最后,打印获得的计数。
下面是上述方法的实现:
C++14
// C++14 program to implement
// the above approach
#include
using namespace std;
// Function to count ways to select N distinct
// pairs of candies with different colours
int numOfWays(vector> a, int n,
int i, set &blue)
{
// If n pairs are selected
if (i == n)
return 1;
// Stores count of ways
// to select the i-th pair
int count = 0;
// Iterate over the range [0, n]
for(int j = 0; j < n; j++)
{
// If pair (i, j) is not included
if (a[i][j] == 1 && blue.find(j) == blue.end())
{
blue.insert(j);
count += numOfWays(a, n, i + 1, blue);
blue.erase(j);
}
}
return count;
}
// Driver Code
int main()
{
int n = 3;
vector> mat = { { 0, 1, 1 },
{ 1, 0, 1 },
{ 1, 1, 1 } };
set mpp;
cout << (numOfWays(mat, n, 0, mpp));
}
// This code is contributed by mohit kumar 29
Java
// Java program to implement
// the above approach
import java.io.*;
import java.lang.*;
import java.util.*;
class GFG{
// Function to count ways to select N distinct
// pairs of candies with different colours
static int numOfWays(int a[][], int n, int i,
HashSet blue)
{
// If n pairs are selected
if (i == n)
return 1;
// Stores count of ways
// to select the i-th pair
int count = 0;
// Iterate over the range [0, n]
for(int j = 0; j < n; j++)
{
// If pair (i, j) is not included
if (a[i][j] == 1 && !blue.contains(j))
{
blue.add(j);
count += numOfWays(a, n, i + 1, blue);
blue.remove(j);
}
}
return count;
}
// Driver Code
public static void main(String[] args)
{
int n = 3;
int mat[][] = { { 0, 1, 1 },
{ 1, 0, 1 },
{ 1, 1, 1 } };
HashSet mpp = new HashSet<>();
System.out.println((numOfWays(mat, n, 0, mpp)));
}
}
// This code is contributed by Kingash
Python3
# Python3 program to implement
# the above approach
# Function to count ways to select N distinct
# pairs of candies with different colours
def numOfWays(a, n, i = 0, blue = []):
# If n pairs are selected
if i == n:
return 1
# Stores count of ways
# to select the i-th pair
count = 0
# Iterate over the range [0, n]
for j in range(n):
# If pair (i, j) is not included
if mat[i][j] == 1 and j not in blue:
count += numOfWays(mat, n, i + 1,
blue + [j])
return count
# Driver Code
if __name__ == "__main__":
n = 3
mat = [ [0, 1, 1],
[1, 0, 1],
[1, 1, 1] ]
print(numOfWays(mat, n))
C#
// C# program to implement
// the above approach
using System;
using System.Collections.Generic;
class GFG{
// Function to count ways to select N distinct
// pairs of candies with different colours
static int numOfWays(int[,] a, int n, int i,
HashSet blue)
{
// If n pairs are selected
if (i == n)
return 1;
// Stores count of ways
// to select the i-th pair
int count = 0;
// Iterate over the range [0, n]
for(int j = 0; j < n; j++)
{
// If pair (i, j) is not included
if (a[i, j] == 1 && !blue.Contains(j))
{
blue.Add(j);
count += numOfWays(a, n, i + 1, blue);
blue.Remove(j);
}
}
return count;
}
// Driver Code
public static void Main()
{
int n = 3;
int[,] mat = { { 0, 1, 1 },
{ 1, 0, 1 },
{ 1, 1, 1 } };
HashSet mpp = new HashSet();
Console.WriteLine((numOfWays(mat, n, 0, mpp)));
}
}
// This code is contributed by ukasp
Javascript
Python3
# Python program to implement
# the above approach
# Function to count ways to select N distinct
# pairs of candies with different colors
def numOfWays(a, n):
# dp[i][j]: Stores count of ways to make
# pairs between i red candies and N blue candies
dp = [[0]*((1 << n)+1) for _ in range(n + 1)]
# If there is no red and blue candy,
# the count of ways to make n pairs is 1
dp[0][0] = 1
# i: Stores count of red candy
for i in range(n):
# j generates a permutation of blue
# candy of selected / not selected
# as a binary number with n bits
for j in range(1 << n):
if dp[i][j] == 0:
continue
# Iterate over the range [0, n]
for k in range(n):
# Create a mask with only
# the k-th bit as set
mask = 1 << k
# If Kth bit of mask is
# unset and mat[i][k] = 1
if not(mask & j) and a[i][k]:
dp[i + 1][j | mask] += dp[i][j]
# Return the dp states, where n red
# and n blue candies are selected
return dp[n][(1 << n)-1]
# Driver Code
if __name__ == "__main__":
n = 3
mat = [[0, 1, 1],
[1, 0, 1],
[1, 1, 1]]
print(numOfWays(mat, n))
3
时间复杂度: O(N!)
辅助空间: O(1)
高效方法:上述方法可以针对使用位屏蔽的动态编程进行优化。对于每个红色糖果,不是生成N 个蓝色糖果的所有排列,而是使用mask ,其中第j位掩码检查第j个蓝色糖果是否可用于选择当前对。
求解该问题的递推关系如下:
If Kth bit of mask is unset and mat[i][k] = 1:
dp[i + 1][j | (1 << k)] += dp[i][j]
where, (j | (1 << k)) marks the kth blue candy as selected.
dp[i][j] = Count of ways to make pairs between i red candy and N blue candies, where j is a permutation of N bit number ranging from 0 to 2N – 1).
请按照以下步骤解决问题:
- 初始化一个二维数组,比如dp[][] ,其中dp[i][j]存储在i 个红色糖果和N 个蓝色糖果之间配对的方法计数。 j表示从0到2 N -1的N位数的排列。
- 使用上面的递推关系并填充递推关系的所有可能的dp状态。
- 最后,打印选择了N 个红色糖果和N 个蓝色糖果的 dp 状态,即dp[i][2 n -1] 。
下面是上述方法的实现:
蟒蛇3
# Python program to implement
# the above approach
# Function to count ways to select N distinct
# pairs of candies with different colors
def numOfWays(a, n):
# dp[i][j]: Stores count of ways to make
# pairs between i red candies and N blue candies
dp = [[0]*((1 << n)+1) for _ in range(n + 1)]
# If there is no red and blue candy,
# the count of ways to make n pairs is 1
dp[0][0] = 1
# i: Stores count of red candy
for i in range(n):
# j generates a permutation of blue
# candy of selected / not selected
# as a binary number with n bits
for j in range(1 << n):
if dp[i][j] == 0:
continue
# Iterate over the range [0, n]
for k in range(n):
# Create a mask with only
# the k-th bit as set
mask = 1 << k
# If Kth bit of mask is
# unset and mat[i][k] = 1
if not(mask & j) and a[i][k]:
dp[i + 1][j | mask] += dp[i][j]
# Return the dp states, where n red
# and n blue candies are selected
return dp[n][(1 << n)-1]
# Driver Code
if __name__ == "__main__":
n = 3
mat = [[0, 1, 1],
[1, 0, 1],
[1, 1, 1]]
print(numOfWays(mat, n))
3
时间复杂度: O(N 2 * 2 N )
辅助空间: O(N * 2 N )