Input: hats =[[3,4],[4,5],[5]]Output: 1Explanation: There is only one way to choose hats given the conditions.First person choose hat 3, Second person choose hat 4 and last one hat 5.
Input: hats =[[1,2,3,4],[1,2,3,4],[1,2,3,4],[1,2,3,4]]Output: 24Explanation: Each person can choose hats labeled from 1 to 4.Number of Permutations of(1,2,3,4)=24.
We use bitmask DP to represent which people have already been assigned hats. For each hat, we try to assign it to any person who likes it and hasn’t been assigned a hat yet. We iterate over all hats and update the DP accordingly.
classSolution {
funnumberWays(hats: List<List<Int>>): Int {
val n = hats.size
val mod = 1_000_000_007
val hat2people = Array(41) { mutableListOf<Int>() }
for (i in0 until n)
for (h in hats[i]) hat2people[h].add(i)
var dp = IntArray(1 shl n)
dp[0] = 1for (h in1..40) {
val ndp = dp.copyOf()
for (mask in0 until (1 shl n)) {
for (p in hat2people[h]) {
if (mask and (1 shl p) ==0) {
ndp[mask or (1 shl p)] = (ndp[mask or (1 shl p)] + dp[mask]) % mod
}
}
}
dp = ndp
}
return dp[(1 shl n) - 1]
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
classSolution:
defnumberWays(self, hats: list[list[int]]) -> int:
n, mod = len(hats), 10**9+7 hat2people = [[] for _ in range(41)]
for i, hs in enumerate(hats):
for h in hs:
hat2people[h].append(i)
dp = [0] * (1<<n)
dp[0] =1for h in range(1, 41):
ndp = dp[:]
for mask in range(1<<n):
for p in hat2people[h]:
ifnot (mask & (1<<p)):
ndp[mask | (1<<p)] = (ndp[mask | (1<<p)] + dp[mask]) % mod
dp = ndp
return dp[(1<<n)-1]