Matching
Solución
Si definimos como la cantidad de matchings de las mujeres del conjunto con los primeros hombres, este problema se reduce a lo siguiente:
(Los : significan “tal que”.)
En palabras, esto equivale a lo siguiente:
La cantidad de matchings en un subconjunto que incluyen a una cierta mujer es equivalente a la suma de todos los matchings sin la mujer donde la mujer es compatible con el -ésimo hombre.
Nuestro caso base es el conjunto vacío, que tiene valor (el conjunto vacío puede considerarse como un único matching que involucra cero pares).
Implementación
Complejidad temporal:
#include <bits/stdc++.h>
using namespace std;
const int MOD = 1e9 + 7;
const int MAX_N = 21;
bool compat[MAX_N][MAX_N];
int dp[1 << MAX_N];
int main() {
int N;
cin >> N;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) { cin >> compat[i][j]; }
}
dp[0] = 1;
for (int s = 0; s < (1 << N); s++) {
int pair_num = __builtin_popcount(s);
for (int w = 0; w < N; w++) {
/*
* comprobamos que
* 1. esta mujer aún no ha sido emparejada
* 2. además es compatible con el {pair_num + 1}-ésimo hombre
*/
if ((s & (1 << w)) || !compat[pair_num][w]) continue;
// sumamos la cantidad a los estados futuros de DP
dp[s | (1 << w)] += dp[s];
dp[s | (1 << w)] %= MOD;
}
}
cout << dp[(1 << N) - 1] << endl;
}import java.io.*;
import java.util.*;
public class Main {
public static final int MOD = (int)1e9 + 7;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
boolean[][] compat = new boolean[N][N];
for (int m = 0; m < N; m++) {
StringTokenizer st = new StringTokenizer(br.readLine());
for (int w = 0; w < N; w++) {
compat[m][w] = (Integer.parseInt(st.nextToken()) == 1);
}
}
int[] dp = new int[1 << N];
dp[0] = 1;
for (int s = 0; s < (1 << N); s++) {
int pair_num = Integer.bitCount(s);
for (int w = 0; w < N; w++) {
/*
* comprobamos que
* 1. esta mujer aún no ha sido emparejada
* 2. además es compatible con el {pair_num + 1}-ésimo hombre
*/
if ((s & (1 << w)) != 0 || !compat[pair_num][w]) continue;
// sumamos la cantidad a los estados futuros de DP
dp[s | (1 << w)] += dp[s];
dp[s | (1 << w)] %= MOD;
}
}
System.out.println(dp[(1 << N) - 1]);
}
}MOD = 10**9 + 7
MAX_N = 21
n = int(input())
compat = []
for _ in range(n):
compat.append(list(map(int, input().split())))
dp = [0] * (1 << n)
dp[0] = 1
for s in range(1 << n):
pair_num = bin(s).count("1")
for w in range(n):
"""
comprobamos que
1. esta mujer aún no ha sido emparejada
2. es compatible con el {pair_num + 1}-ésimo hombre
"""
if (s & (1 << w)) or not compat[pair_num][w]:
continue
# sumamos el conteo a los estados futuros de DP
dp[s | (1 << w)] += dp[s]
dp[s | (1 << w)] %= MOD
print(dp[(1 << n) - 1])