題目連結:
給定一個大小為 10 × 10 的字元矩陣,代表 100 個燈泡的開關狀態。「#」代表燈泡是開的,「O」代表關著。而每將一個燈泡打開(或關上),會順帶改變相鄰燈泡(上、下、左、右)的開關狀態。
求將所有燈泡關上最少需要開關幾個燈泡?
3
##########
##########
##########
##########
##########
##########
##########
##########
##########
##########
OOOOOOOOOO
OOOOOOOOOO
OOOOOOOOOO
OOOOOOOOOO
OOOOOOOOOO
OOOOOOOOOO
OOOOOOOOOO
OOOOOOOOOO
OOOOOOOOOO
OOOOOOOOOO
#O########
OOO#######
#O########
####OO####
###O##O###
####OO####
##########
########O#
#######OOO
########O#
窮舉第一列的開關方法,以下是示意圖:
所以會有 2 ^ 10 = 1024 個可能的分支(每個燈泡都可以選擇要不要改變)。
而剩下的列數就按照前一列的開關狀態去開關,例如像是:
第一列為 ##OO##OOOO
第二列為 ##########
因為第一列有一些是開的,我們需要把它關上,因此我們將第二列藍色位置的燈泡打開。
就這樣做到第十列的時候,如果還有燈泡是開的,表示第一列的開關方法無效;如果全關上了,就有可能是最佳的開關方法,還要跟其他的方法比較開關次數。
至於為何這樣子一定會包含到最佳解,以下稍作解釋:
因為每一列會互相影響,第一列影響第二列的燈泡,第二列影響第一、三列等等。而我們可以看到第一列處在邊緣地帶。
當我們窮舉出第一列的開關狀況後,也就只剩下了第二列可以影響它的狀況,也就固定了第二列的開關方式(因為我們要把所有燈泡關上),且第三、四、五 …… 列也是同理。
而我們知道在最佳解下,一個燈泡最多只會主動地變動一次(將其打開或是關上),因為變動兩次會抵消效果,導致一定不是最佳解。正因如此,窮舉了第一列方法之後,一定有其中一種是最佳解第一列的開關狀態。
這就是為何一定會包含到最佳解。而也不一定要窮舉第一列,以這題來說第十列、第一行、第十行都可行,因為都是處於矩陣邊緣的行列。
此次分享到此為止,如有任何更加簡潔的想法或是有說明不清楚之地方,也煩請各位大大撥冗討論。