Skip to content

Commit 884016f

Browse files
committed
feat: add solutions to lc problem: No.1434
No.1434.Number of Ways to Wear Different Hats to Each Other
1 parent 2299f9b commit 884016f

File tree

7 files changed

+339
-196
lines changed

7 files changed

+339
-196
lines changed

solution/1400-1499/1434.Number of Ways to Wear Different Hats to Each Other/README.md

Lines changed: 120 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,23 @@
6565

6666
<!-- 这里可写通用的实现逻辑 -->
6767

68-
**方法一:状态压缩 DP**
68+
**方法一:状态压缩动态规划**
69+
70+
我们注意到 $n$ 不超过 $10$,因此我们考虑使用状态压缩动态规划的方法求解。
71+
72+
我们定义 $f[i][j]$ 表示在前 $i$ 个帽子中,当前被分配的人的状态为 $j$ 时的方案数。其中 $j$ 是一个二进制数,表示当前被分配的人的集合。初始时 $f[0][0]=1$,答案为 $f[m][2^n - 1]$,其中 $m$ 是帽子的最大编号,而 $n$ 是人的数量。
73+
74+
考虑 $f[i][j]$,如果第 $i$ 个帽子不分配给任何人,那么 $f[i][j]=f[i-1][j]$;如果第 $i$ 个帽子分配给了喜欢它的人 $k$,那么 $f[i][j]=f[i-1][j \oplus 2^k]$。这里 $\oplus$ 表示异或运算。因此我们可以得到状态转移方程:
75+
76+
$$
77+
f[i][j]=f[i-1][j]+ \sum_{k \in like[i]} f[i-1][j \oplus 2^k]
78+
$$
79+
80+
其中 $like[i]$ 表示喜欢第 $i$ 个帽子的人的集合。
81+
82+
最终的答案即为 $f[m][2^n - 1]$,注意答案可能很大,需要对 $10^9 + 7$ 取模。
83+
84+
时间复杂度 $O(m \times 2^n \times n)$,空间复杂度 $O(m \times 2^n)$。其中 $m$ 是帽子的最大编号,本题中 $m \leq 40$;而 $n$ 是人的数量,本题中 $n \leq 10$。
6985

7086
<!-- tabs:start -->
7187

@@ -76,23 +92,22 @@
7692
```python
7793
class Solution:
7894
def numberWays(self, hats: List[List[int]]) -> int:
79-
d = defaultdict(list)
95+
g = defaultdict(list)
8096
for i, h in enumerate(hats):
8197
for v in h:
82-
d[v].append(i)
98+
g[v].append(i)
99+
mod = 10**9 + 7
83100
n = len(hats)
84-
mx = max(max(h) for h in hats)
85-
dp = [[0] * (1 << n) for _ in range(mx + 1)]
86-
dp[0][0] = 1
87-
mod = int(1e9) + 7
88-
for i in range(1, mx + 1):
89-
for mask in range(1 << n):
90-
dp[i][mask] = dp[i - 1][mask]
91-
for j in d[i]:
92-
if (mask >> j) & 1:
93-
dp[i][mask] += dp[i - 1][mask ^ (1 << j)]
94-
dp[i][mask] %= mod
95-
return dp[mx][(1 << n) - 1]
101+
m = max(max(h) for h in hats)
102+
f = [[0] * (1 << n) for _ in range(m + 1)]
103+
f[0][0] = 1
104+
for i in range(1, m + 1):
105+
for j in range(1 << n):
106+
f[i][j] = f[i - 1][j]
107+
for k in g[i]:
108+
if j >> k & 1:
109+
f[i][j] = (f[i][j] + f[i - 1][j ^ (1 << k)]) % mod
110+
return f[m][-1]
96111
```
97112

98113
### **Java**
@@ -101,67 +116,71 @@ class Solution:
101116

102117
```java
103118
class Solution {
104-
private static final int MOD = (int) 1e9 + 7;
105-
106119
public int numberWays(List<List<Integer>> hats) {
107-
List<Integer>[] d = new List[41];
108-
Arrays.setAll(d, k -> new ArrayList<>());
109120
int n = hats.size();
110-
int mx = 0;
121+
int m = 0;
122+
for (var h : hats) {
123+
for (int v : h) {
124+
m = Math.max(m, v);
125+
}
126+
}
127+
List<Integer>[] g = new List[m + 1];
128+
Arrays.setAll(g, k -> new ArrayList<>());
111129
for (int i = 0; i < n; ++i) {
112-
for (int h : hats.get(i)) {
113-
d[h].add(i);
114-
mx = Math.max(mx, h);
130+
for (int v : hats.get(i)) {
131+
g[v].add(i);
115132
}
116133
}
117-
long[][] dp = new long[mx + 1][1 << n];
118-
dp[0][0] = 1;
119-
for (int i = 1; i < mx + 1; ++i) {
120-
for (int mask = 0; mask < 1 << n; ++mask) {
121-
dp[i][mask] = dp[i - 1][mask];
122-
for (int j : d[i]) {
123-
if (((mask >> j) & 1) == 1) {
124-
dp[i][mask] = (dp[i][mask] + dp[i - 1][mask ^ (1 << j)]) % MOD;
134+
final int mod = (int) 1e9 + 7;
135+
int[][] f = new int[m + 1][1 << n];
136+
f[0][0] = 1;
137+
for (int i = 1; i <= m; ++i) {
138+
for (int j = 0; j < 1 << n; ++j) {
139+
f[i][j] = f[i - 1][j];
140+
for (int k : g[i]) {
141+
if ((j >> k & 1) == 1) {
142+
f[i][j] = (f[i][j] + f[i - 1][j ^ (1 << k)]) % mod;
125143
}
126144
}
127145
}
128146
}
129-
return (int) dp[mx][(1 << n) - 1];
147+
return f[m][(1 << n) - 1];
130148
}
131149
}
132150
```
133151

134152
### **C++**
135153

136154
```cpp
137-
using ll = long long;
138-
139155
class Solution {
140156
public:
141157
int numberWays(vector<vector<int>>& hats) {
142-
vector<vector<int>> d(41);
143158
int n = hats.size();
144-
int mx = 0;
159+
int m = 0;
160+
for (auto& h : hats) {
161+
m = max(m, *max_element(h.begin(), h.end()));
162+
}
163+
vector<vector<int>> g(m + 1);
145164
for (int i = 0; i < n; ++i) {
146-
for (int& h : hats[i]) {
147-
d[h].push_back(i);
148-
mx = max(mx, h);
165+
for (int& v : hats[i]) {
166+
g[v].push_back(i);
149167
}
150168
}
151-
vector<vector<ll>> dp(mx + 1, vector<ll>(1 << n));
152-
dp[0][0] = 1;
153-
int mod = 1e9 + 7;
154-
for (int i = 1; i <= mx; ++i) {
155-
for (int mask = 0; mask < 1 << n; ++mask) {
156-
dp[i][mask] = dp[i - 1][mask];
157-
for (int& j : d[i]) {
158-
if ((mask >> j) & 1) {
159-
dp[i][mask] = (dp[i][mask] + dp[i - 1][mask ^ (1 << j)]) % mod;
169+
const int mod = 1e9 + 7;
170+
int f[m + 1][1 << n];
171+
memset(f, 0, sizeof(f));
172+
f[0][0] = 1;
173+
for (int i = 1; i <= m; ++i) {
174+
for (int j = 0; j < 1 << n; ++j) {
175+
f[i][j] = f[i -1][j];
176+
for (int k : g[i]) {
177+
if (j >> k & 1) {
178+
f[i][j] = (f[i][j] + f[i - 1][j ^ (1 << k)]) % mod;
160179
}
161180
}
162181
}
163182
}
164-
return dp[mx][(1 << n) - 1];
183+
return f[m][(1 << n) - 1];
165184
}
166185
};
167186
```
@@ -170,32 +189,36 @@ public:
170189
171190
```go
172191
func numberWays(hats [][]int) int {
173-
d := make([][]int, 41)
174-
mx := 0
192+
n := len(hats)
193+
m := 0
194+
for _, h := range hats {
195+
for _, v := range h {
196+
m = max(m, v)
197+
}
198+
}
199+
g := make([][]int, m+1)
175200
for i, h := range hats {
176201
for _, v := range h {
177-
d[v] = append(d[v], i)
178-
mx = max(mx, v)
202+
g[v] = append(g[v], i)
179203
}
180204
}
181-
dp := make([][]int, mx+1)
182-
n := len(hats)
183-
for i := range dp {
184-
dp[i] = make([]int, 1<<n)
205+
const mod = 1e9 + 7
206+
f := make([][]int, m+1)
207+
for i := range f {
208+
f[i] = make([]int, 1<<n)
185209
}
186-
dp[0][0] = 1
187-
mod := int(1e9) + 7
188-
for i := 1; i <= mx; i++ {
189-
for mask := 0; mask < 1<<n; mask++ {
190-
dp[i][mask] = dp[i-1][mask]
191-
for _, j := range d[i] {
192-
if ((mask >> j) & 1) == 1 {
193-
dp[i][mask] = (dp[i][mask] + dp[i-1][mask^(1<<j)]) % mod
210+
f[0][0] = 1
211+
for i := 1; i <= m; i++ {
212+
for j := 0; j < 1<<n; j++ {
213+
f[i][j] = f[i-1][j]
214+
for _, k := range g[i] {
215+
if j>>k&1 == 1 {
216+
f[i][j] = (f[i][j] + f[i-1][j^(1<<k)]) % mod
194217
}
195218
}
196219
}
197220
}
198-
return dp[mx][(1<<n)-1]
221+
return f[m][(1<<n)-1]
199222
}
200223
201224
func max(a, b int) int {
@@ -206,6 +229,37 @@ func max(a, b int) int {
206229
}
207230
```
208231

232+
### **TypeScript**
233+
234+
```ts
235+
function numberWays(hats: number[][]): number {
236+
const n = hats.length;
237+
const m = Math.max(...hats.flat());
238+
const g: number[][] = Array.from({ length: m + 1 }, () => []);
239+
for (let i = 0; i < n; ++i) {
240+
for (const v of hats[i]) {
241+
g[v].push(i);
242+
}
243+
}
244+
const f: number[][] = Array.from({ length: m + 1 }, () =>
245+
Array.from({ length: 1 << n }, () => 0),
246+
);
247+
f[0][0] = 1;
248+
const mod = 1e9 + 7;
249+
for (let i = 1; i <= m; ++i) {
250+
for (let j = 0; j < 1 << n; ++j) {
251+
f[i][j] = f[i - 1][j];
252+
for (const k of g[i]) {
253+
if (((j >> k) & 1) === 1) {
254+
f[i][j] = (f[i][j] + f[i - 1][j ^ (1 << k)]) % mod;
255+
}
256+
}
257+
}
258+
}
259+
return f[m][(1 << n) - 1];
260+
}
261+
```
262+
209263
### **...**
210264

211265
```

0 commit comments

Comments
 (0)