Cái q3 nó là thế này, zigzag nghĩa là 3 phần tử liên tiếp nó form cái shape như này \/ hoặc là /\.
Nếu dpUp[index][val] là số cách chọn ở index i với val mà index tiếp theo là up, thì số cách chọn dpUp[index][val] sẽ là tổng của dpDown[i-1][preVal] ở đây preVal phải > val hiện tại mình muốn chọn. Để có thể form đc cái shape như này \/.
Tương tự với dpDown[index][val] nó sẽ form đc cái shape Zigzag như này
/\, số cách chọn dpDown[index][val] sẽ là tổng của dpUp[i-1][preVal] ở đây preVal phải < val
Python:
class Solution:
def zigZagArrays(self, n: int, l: int, r: int) -> int:
MOD = 10**9 + 7
up = [0] * (r + 2)
down = [0] * (r + 2)
for j in range(l, r + 1):
up[j] = 1
down[j] = 1
prefixUp = [0] * (r + 2)
postfixDown = [0] * (r + 2)
s = 0
for j in range(l, r + 1):
s += up[j]
prefixUp[j] = s % MOD
s = 0
for j in range(r, l - 1, -1):
s += down[j]
postfixDown[j] = s % MOD
for _ in range(1, n):
cUp = [0] * (r + 2)
cDown = [0] * (r + 2)
for j in range(l, r + 1):
cUp[j] = postfixDown[j + 1]
cDown[j] = prefixUp[j - 1]
up, down = cUp, cDown
s = 0
for j in range(l, r + 1):
s += up[j]
prefixUp[j] = s % MOD
s = 0
for j in range(r, l - 1, -1):
s += down[j]
postfixDown[j] = s % MOD
return (sum(up[l:r + 1]) + sum(down[l:r + 1])) % MOD
Nếu nghĩ theo hướng index là phần tử middle giữa 3 phần tử để form 1 cái zigzag thì implement khá dễ với prefixSum với bottom up, mình đi dp topdown rồi maintain cái biến streak nên ko làm ra do time complexity cao quá.