Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 7061c5b

Browse files
feat: add solutions to lc problem: No.1931 (doocs#1999)
No.1931.Painting a Grid With Three Different Colors
1 parent 01f1e47 commit 7061c5b

File tree

7 files changed

+890
-0
lines changed

7 files changed

+890
-0
lines changed

‎solution/1900-1999/1931.Painting a Grid With Three Different Colors/README.md‎

Lines changed: 307 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,22 +48,329 @@
4848

4949
<!-- 这里可写通用的实现逻辑 -->
5050

51+
**方法一:状态压缩 + 动态规划**
52+
53+
我们注意到,网格的行数不超过 5ドル,ドル那么一列中最多有 3ドル^5=243$ 种不同的颜色方案。
54+
55+
因此,我们定义 $f[i][j]$ 表示前 $i$ 列中,第 $i$ 列的涂色状态为 $j$ 的方案数。状态 $f[i][j]$ 由 $f[i - 1][k]$ 转移而来,其中 $k$ 是第 $i - 1$ 列的涂色状态,且 $k$ 和 $j$ 满足不同颜色相邻的要求。即:
56+
57+
$$
58+
f[i][j] = \sum_{k \in \text{valid}(j)} f[i - 1][k]
59+
$$
60+
61+
其中 $\text{valid}(j)$ 表示状态 $j$ 的所有合法前驱状态。
62+
63+
最终的答案即为 $f[n][j]$ 的总和,其中 $j$ 是任意合法的状态。
64+
65+
我们注意到,$f[i][j]$ 只和 $f[i - 1][k]$ 有关,因此我们可以使用滚动数组优化空间复杂度。
66+
67+
时间复杂度 $O((m + n) \times 3^{2m}),ドル空间复杂度 $O(3^m)$。其中 $m$ 和 $n$ 分别是网格的行数和列数。
68+
5169
<!-- tabs:start -->
5270

5371
### **Python3**
5472

5573
<!-- 这里可写当前语言的特殊实现逻辑 -->
5674

5775
```python
76+
class Solution:
77+
def colorTheGrid(self, m: int, n: int) -> int:
78+
def f1(x: int) -> bool:
79+
last = -1
80+
for _ in range(m):
81+
if x % 3 == last:
82+
return False
83+
last = x % 3
84+
x //= 3
85+
return True
86+
87+
def f2(x: int, y: int) -> bool:
88+
for _ in range(m):
89+
if x % 3 == y % 3:
90+
return False
91+
x, y = x // 3, y // 3
92+
return True
5893

94+
mod = 10**9 + 7
95+
mx = 3**m
96+
valid = {i for i in range(mx) if f1(i)}
97+
d = defaultdict(list)
98+
for x in valid:
99+
for y in valid:
100+
if f2(x, y):
101+
d[x].append(y)
102+
f = [int(i in valid) for i in range(mx)]
103+
for _ in range(n - 1):
104+
g = [0] * mx
105+
for i in valid:
106+
for j in d[i]:
107+
g[i] = (g[i] + f[j]) % mod
108+
f = g
109+
return sum(f) % mod
59110
```
60111

61112
### **Java**
62113

63114
<!-- 这里可写当前语言的特殊实现逻辑 -->
64115

65116
```java
117+
class Solution {
118+
private int m;
119+
120+
public int colorTheGrid(int m, int n) {
121+
this.m = m;
122+
final int mod = (int) 1e9 + 7;
123+
int mx = (int) Math.pow(3, m);
124+
Set<Integer> valid = new HashSet<>();
125+
for (int i = 0; i < mx; ++i) {
126+
if (f1(i)) {
127+
valid.add(i);
128+
}
129+
}
130+
Map<Integer, List<Integer>> d = new HashMap<>();
131+
for (int i : valid) {
132+
for (int j : valid) {
133+
if (f2(i, j)) {
134+
d.computeIfAbsent(i, k -> new ArrayList<>()).add(j);
135+
}
136+
}
137+
}
138+
int[] f = new int[mx];
139+
for (int i = 0; i < mx; ++i) {
140+
f[i] = valid.contains(i) ? 1 : 0;
141+
}
142+
for (int k = 1; k < n; ++k) {
143+
int[] g = new int[mx];
144+
for (int i : valid) {
145+
for (int j : d.getOrDefault(i, List.of())) {
146+
g[i] = (g[i] + f[j]) % mod;
147+
}
148+
}
149+
f = g;
150+
}
151+
int ans = 0;
152+
for (int x : f) {
153+
ans = (ans + x) % mod;
154+
}
155+
return ans;
156+
}
157+
158+
private boolean f1(int x) {
159+
int last = -1;
160+
for (int i = 0; i < m; ++i) {
161+
if (x % 3 == last) {
162+
return false;
163+
}
164+
last = x % 3;
165+
x /= 3;
166+
}
167+
return true;
168+
}
169+
170+
private boolean f2(int x, int y) {
171+
for (int i = 0; i < m; ++i) {
172+
if (x % 3 == y % 3) {
173+
return false;
174+
}
175+
x /= 3;
176+
y /= 3;
177+
}
178+
return true;
179+
}
180+
}
181+
```
182+
183+
### **C++**
184+
185+
```cpp
186+
class Solution {
187+
public:
188+
int colorTheGrid(int m, int n) {
189+
auto f1 = [&](int x) {
190+
int last = -1;
191+
for (int i = 0; i < m; ++i) {
192+
if (x % 3 == last) {
193+
return false;
194+
}
195+
last = x % 3;
196+
x /= 3;
197+
}
198+
return true;
199+
};
200+
auto f2 = [&](int x, int y) {
201+
for (int i = 0; i < m; ++i) {
202+
if (x % 3 == y % 3) {
203+
return false;
204+
}
205+
x /= 3;
206+
y /= 3;
207+
}
208+
return true;
209+
};
210+
211+
const int mod = 1e9 + 7;
212+
int mx = pow(3, m);
213+
unordered_set<int> valid;
214+
for (int i = 0; i < mx; ++i) {
215+
if (f1(i)) {
216+
valid.insert(i);
217+
}
218+
}
219+
unordered_map<int, vector<int>> d;
220+
for (int i : valid) {
221+
for (int j : valid) {
222+
if (f2(i, j)) {
223+
d[i].push_back(j);
224+
}
225+
}
226+
}
227+
vector<int> f(mx);
228+
for (int i = 0; i < mx; ++i) {
229+
f[i] = valid.count(i);
230+
}
231+
for (int k = 1; k < n; ++k) {
232+
vector<int> g(mx);
233+
for (int i : valid) {
234+
for (int j : d[i]) {
235+
g[i] = (g[i] + f[j]) % mod;
236+
}
237+
}
238+
f = move(g);
239+
}
240+
int ans = 0;
241+
for (int x : f) {
242+
ans = (ans + x) % mod;
243+
}
244+
return ans;
245+
}
246+
};
247+
```
248+
249+
### **Go**
250+
251+
```go
252+
func colorTheGrid(m int, n int) (ans int) {
253+
f1 := func(x int) bool {
254+
last := -1
255+
for i := 0; i < m; i++ {
256+
if x%3 == last {
257+
return false
258+
}
259+
last = x % 3
260+
x /= 3
261+
}
262+
return true
263+
}
264+
f2 := func(x, y int) bool {
265+
for i := 0; i < m; i++ {
266+
if x%3 == y%3 {
267+
return false
268+
}
269+
x /= 3
270+
y /= 3
271+
}
272+
return true
273+
}
274+
mx := int(math.Pow(3, float64(m)))
275+
valid := map[int]bool{}
276+
for i := 0; i < mx; i++ {
277+
if f1(i) {
278+
valid[i] = true
279+
}
280+
}
281+
d := map[int][]int{}
282+
for i := range valid {
283+
for j := range valid {
284+
if f2(i, j) {
285+
d[i] = append(d[i], j)
286+
}
287+
}
288+
}
289+
f := make([]int, mx)
290+
for i := 0; i < mx; i++ {
291+
if valid[i] {
292+
f[i] = 1
293+
}
294+
}
295+
const mod int = 1e9 + 7
296+
for k := 1; k < n; k++ {
297+
g := make([]int, mx)
298+
for i := range valid {
299+
for _, j := range d[i] {
300+
g[i] = (g[i] + f[j]) % mod
301+
}
302+
}
303+
f = g
304+
}
305+
for _, x := range f {
306+
ans = (ans + x) % mod
307+
}
308+
return
309+
}
310+
```
311+
312+
### **TypeScript**
66313

314+
```ts
315+
function colorTheGrid(m: number, n: number): number {
316+
const f1 = (x: number): boolean => {
317+
let last = -1;
318+
for (let i = 0; i < m; ++i) {
319+
if (x % 3 === last) {
320+
return false;
321+
}
322+
last = x % 3;
323+
x = Math.floor(x / 3);
324+
}
325+
return true;
326+
};
327+
const f2 = (x: number, y: number): boolean => {
328+
for (let i = 0; i < m; ++i) {
329+
if (x % 3 === y % 3) {
330+
return false;
331+
}
332+
x = Math.floor(x / 3);
333+
y = Math.floor(y / 3);
334+
}
335+
return true;
336+
};
337+
const mx = 3 ** m;
338+
const valid = new Set<number>();
339+
for (let i = 0; i < mx; ++i) {
340+
if (f1(i)) {
341+
valid.add(i);
342+
}
343+
}
344+
const d: Map<number, number[]> = new Map();
345+
for (const i of valid) {
346+
for (const j of valid) {
347+
if (f2(i, j)) {
348+
d.set(i, (d.get(i) || []).concat(j));
349+
}
350+
}
351+
}
352+
const f: number[] = Array(mx).fill(0);
353+
for (let i = 0; i < mx; ++i) {
354+
if (valid.has(i)) {
355+
f[i] = 1;
356+
}
357+
}
358+
const mod = 10 ** 9 + 7;
359+
for (let k = 1; k < n; ++k) {
360+
const g: number[] = Array(mx).fill(0);
361+
for (const i of valid) {
362+
for (const j of d.get(i) || []) {
363+
g[i] = (g[i] + f[j]) % mod;
364+
}
365+
}
366+
f.splice(0, f.length, ...g);
367+
}
368+
let ans = 0;
369+
for (const x of f) {
370+
ans = (ans + x) % mod;
371+
}
372+
return ans;
373+
}
67374
```
68375

69376
### **...**

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /