โจทย์: กำหนดให้มีเมทริกซ์ไบนารี (0 = ช่องว่าง, 1 = กำแพง) เริ่มจากช่องว่างแถวแรก ต้องไปถึงช่องว่างแถวสุดท้าย สามารถเคลื่อนที่ซ้าย ขวา ล่าง ได้ ต้องการหาเส้นทางที่ยาวที่สุดที่ไม่ซ้ำช่อง (Visit each cell at most once) หากไม่สามารถไปถึงได้ คืนค่า 0
ตัวอย่าง
Matrix: 0 0 0 0 0 0 0 1 0 0 0 0
Output: 10
เส้นทาง: (0,3)→(0,2)→(0,1)→(0,0)→(1,0)→(1,1)→(1,2)→(2,2)→(2,1)→(2,0) รวม 10 ช่อง
อัลกอริทึม: Dynamic Programming แบบแถวต่อแถว (Row-by-row DP)
เนื่องจากเคลื่อนที่ได้เฉพาะ ซ้าย ขวา ล่าง (ไม่ขึ้น) จึงสามารถประมวลผลแถวต่อแถวได้
ขั้นตอนการทำงาน
dp[j]= ความยาวเส้นทางสูงสุดที่สิ้นสุดที่คอลัมน์jของแถวปัจจุบัน- สำหรับแต่ละแถว สร้าง
ndp(Left-to-right pass) และndp2(Right-to-left pass) - Left-to-right: เลื่อนจากซ้ายไปขวา อัปเดต
ndp[j] = max(ndp[j], ndp[j-1] + 1) - Right-to-left: เลื่อนจากขวาไปซ้าย อัปเดต
ndp2[j] = max(ndp2[j], ndp2[j+1] + 1)และรวมกับndp - อัปเดต
dp = ndpสำหรับแถวถัดไป
โค้ด Python
def solve(matrix):
N = len(matrix)
M = len(matrix[0])
dp = [-1 for _ in matrix[0]] # เริ่มต้น -1 (ไม่สามารถถึงได้)
for i in range(N):
ndp = [-1 for _ in matrix[0]]
ndp2 = [-1 for _ in matrix[0]]
# เริ่มต้นจากด้านบน (Down move)
for j in range(M):
if matrix[i][j] != 1 and (i == 0 or dp[j] > -1):
ndp[j] = dp[j] + 1
ndp2[j] = dp[j] + 1
# Left-to-right pass (เคลื่อนที่ขวา)
for j in range(1, M):
if matrix[i][j] != 1 and ndp[j - 1] > -1:
ndp[j] = max(ndp[j], ndp[j - 1] + 1)
# Right-to-left pass (เคลื่อนที่ซ้าย)
for j in range(M - 2, -1, -1):
if matrix[i][j] != 1 and ndp2[j + 1] > -1:
ndp2[j] = max(ndp2[j], ndp2[j + 1] + 1)
ndp[j] = max(ndp[j], ndp2[j])
dp = ndp
return max(dp) + 1
# ทดสอบ
matrix = [
[0, 0, 0, 0],
[0, 0, 0, 1],
[0, 0, 0, 0]
]
print(solve(matrix)) # Output: 10
ความซับซ้อน
- Time Complexity: O(N × M) - ประมวลผลแต่ละเซลล์คงที่ครั้ง
- Space Complexity: O(M) - เก็บแค่ 2 แถว DP
รายละเอียดเพิ่มเติม
ndpเก็บค่าที่ได้จากการเคลื่อนที่จากซ้ายไปขวาndp2เก็บค่าที่ได้จากการเคลื่อนที่จากขวาไปซ้าย- การรวม
ndp[j] = max(ndp[j], ndp2[j])ให้ค่าที่ดีที่สุดจากทั้งสองทิศทาง - คืนค่า
max(dp) + 1เพราะ dp นับ "ขั้นตอน" (Edges) แต่โจทย์ถาม "จำนวนโหนด" (Nodes = Edges + 1)