Number of Ways to Wear Different Hats to Each Other
There are n people and 40 types of hats labeled from 1 to 40.
Given a list of list of integers hats, where hats[i] is a list of all hats preferred by the i-th person.
Return the number of ways that the n people wear different hats to each other.
Since the answer may be too large, return it modulo 10^9 + 7.
Example 1:
Input: hats = [[3,4],[4,5],[5]]
Output: 1
Explanation: 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.
Example 2:
Input: hats = [[3,5,1],[3,5]]
Output: 4
Explanation: There are 4 ways to choose hats
(3,5), (5,3), (1,3) and (1,5)
Example 3:
Input: hats = [[1,2,3,4],[1,2,3,4],[1,2,3,4],[1,2,3,4]]
Output: 24
Explanation: Each person can choose hats labeled from 1 to 4.
Number of Permutations of (1,2,3,4) = 24.
/** * The first idea come to our mind is that we will do straightforward like the * problem said: Return the number of ways that the n people wear different hats * to each other. We will assign n people with different hats and use dp to * calculate number of ways. */// But that will result in TLEclassSolution {int mod =1_000_000_007;publicintnumberWays(List<List<Integer>> hats) {int n =hats.size();// h2p[i] indicates the list of people who can wear i_th hatList<Integer>[] h2p =newList[41];for (int i =1; i <=40; i++) h2p[i] =newArrayList<>();for (int i =0; i < n; i++)for (int hat :hats.get(i)) h2p[hat].add(i);// max value of full mask can be 2^n -> 1024Integer[][] dp =newInteger[41][1024];// Using a bitmask where each bit shows whether the ith perseon has been// assigned or notreturndfs(h2p, (1<< n) -1,1,0, dp);// we are using 2 masks here// 1st-> (1<<n)-1 -> this shows the final mask configuration we want to reach// 2nd-> 0 -> this shows the current mask configuration }// dp[i][j] -> ways to assign ith hat to mask value of j// Remember that (i+1)th hat will be assigned after the ith hatintdfs(List<Integer>[] h2p,int allMask,int hat,int assignedPeople,Integer[][] dp) {if (assignedPeople == allMask)return1; // Check if assigned different hats to all peopleif (hat >40)return0; // no more hats to processif (dp[hat][assignedPeople] !=null)return dp[hat][assignedPeople];int ans =dfs(h2p, allMask, hat +1, assignedPeople, dp); // Don't wear this hatfor (int p : h2p[hat]) {// Skip if person `p` was assigned hatif (((assignedPeople >> p) &1) ==1)continue;// Wear this hat for p_th person ans +=dfs(h2p, allMask, hat +1, assignedPeople | (1<< p), dp); ans %= mod; } dp[hat][assignedPeople] = ans;return ans; }}