[英]Dynamic Programming algorithm
給定大小NxM
為0
和1
的矩陣。 如果[i:j]
處存在鼠標,那么它將為1
,否則為0
。 我們必須從[0:0]
並到達[n-1:m-1]
。 我們只能向下或向右走。 如果我們通過位置[x:y]
使|ix|+|jy|<=1
,則位置[i:j]
鼠標會嚇到我們。
找到一條我們被最小數量的不同老鼠嚇到的路徑。 注意單詞distinct,即鼠標如果害怕我們那么它不會再嚇到我們了。
在一次采訪中詢問了這個問題。 我試圖通過一般DP問題中使用的想法解決它,我們可以向下和向右移動並且必須找到最小路徑,但在所有這些問題中我們可以采用最小的[i-1:j]
和[i:j-1]
查找當前索引最小值並從左到右處理所有行。
但是我不能在這里使用這個想法,因為這里有一個鼠標影響4個細胞。
有人能說出如何解決這個問題嗎?
我認為解決這個問題的最簡單(不夠有效)的方法是在NxM頂點的圖上求解最短路徑,使用以下邊成本函數(i和j是引用單元格的圖節點(i',j')和(i',j'')在主矩陣中):
c(i,j) = 1 if [(i',j') and (i'',j'') are sideByside] && [(i'',j'') is scaring] ,
0 otherwise
我認為這個非常簡單的想法(可能不完整但足以滿足面試官的要求)如下。
我們為邊緣分配權重。 首先,所有邊都具有權重0.然后在頂點A中考慮鼠標。頂點A具有4個相鄰邊b,c,d,e,其連接A與頂點B,C,D,E(當A僅有2或者3個相鄰邊緣相似)。 所以現在我們為鄰近頂點B,C,D,E的每個邊緣增加1,除了邊緣b,c,d,e。 現在,頂點A將權重2添加到每個MINIMAL權重路徑“被頂點A嚇到”。 任何可能的4只角鼠都需要特別考慮,我們可以將邊緣權重增加2。
現在我們有一個最簡單的DP問題,即在向下/向右移動的整數點陣中找到最小權重的路徑。 我擔心的是只用1步或2步分開的老鼠。 我很快檢查了,這似乎有效,但我沒有完整的證據。
在每個單元格中,存儲最有效路徑來自的位置(頂部或左側)(在每個單元格中基本上是一個位值)。
當考慮左邊的細胞時,如果那個細胞來自頂部並且當前細胞正上方有一只小鼠,我們就知道它已經嚇到了我們。
插圖:( C
是當前單元格, L
是左邊, S
是L
的來源)
0S1 <- this mouse already scared us 0LC
當將細胞考慮到頂部時,如果該細胞來自左側並且當前細胞的左側有一只小鼠,我們知道它已經嚇到了我們。
插圖:( C
是當前單元格, T
是頂部, S
是T
的來源)
0ST 01C ^- this mouse already scared us
當把細胞考慮到頂部時,如果那個細胞有一只老鼠,我們知道它已經嚇到了我們。
插圖:( C
是當前單元格)
01 <- this mouse already scared us 0C
當考慮左邊的細胞時,如果那個細胞有一只老鼠,我們就知道它已經讓我們害怕了。
插圖:( C
是當前單元格)
01C ^- this mouse already scared us
當考慮到頂部或左側的單元格時,如果當前單元格有鼠標,我們知道它已經嚇到了我們。
插圖:( 1
為當前單元格, L
為左側, T
為頂部)
0T L1 <- this mouse already scared us
從這里推導算法應該不會太困難。
如果我們只是被一只老鼠嚇到了,如果我們通過它的細胞那么問題將是微不足道的。 如果通過其中一個小鼠細胞,只需增加路徑的可怕性。 通過在路徑上的歸納,我們可以記住從給定單元到最終的最佳路徑,然后以通常的DP方式構建到起點。
復雜性是由以下要求產生的:如果我們通過鼠標范圍內的5個單元格之一,那么我們需要增加路徑的可怕性,但只需增加一次。
這可以通過使用寬度為N的位字段來實現,其中N是鼠標的數量,第i位表示該路徑是否會使您害怕第i個鼠標。 然后,DP可以對一個向量(0,0,..,0,1,0,...,0,0)使用按位OR運算,其中1位於第i個鼠標的第i個位置。
但是在找到最佳部分路徑時會遇到問題,因為沒有嚴格的比特字段排序權重相等。 一些簡單的啟發式邏輯表明,您只需關注鼠標周圍9個單元格的區別。 因此,您可以簡單地跟蹤那里附近的一組最佳部分路徑。 保持在鼠標附近的解決方案是最好的解決方案,當沒有被鼠標i嚇到,以及那些你被鼠標嚇到的人。 在接近區分后,兩者不再相關。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.