我喜歡這個 - >最長子序列
1 6 2
8 3 7
4 9 5
矩陣你可以去任何方向,上下左,右斜,你必須找到最長子序列,您可以選擇下一個數字,其絕對差值大於3.
像上述情況一樣,最長的子序列是1->6->2->7->3->8->4->9->5
。
我可以寫一個暴力代碼,它找到最長的序列,就像找到第一個數字,第二個數字等等的最長序列一樣。並返回具有最大計數的那個。
我是DP新手。有沒有其他方法可以通過使用DP來解決這個問題?我無法理解使用DP的解決方案。
我喜歡這個 - >最長子序列
1 6 2
8 3 7
4 9 5
矩陣你可以去任何方向,上下左,右斜,你必須找到最長子序列,您可以選擇下一個數字,其絕對差值大於3.
像上述情況一樣,最長的子序列是1->6->2->7->3->8->4->9->5
。
我可以寫一個暴力代碼,它找到最長的序列,就像找到第一個數字,第二個數字等等的最長序列一樣。並返回具有最大計數的那個。
我是DP新手。有沒有其他方法可以通過使用DP來解決這個問題?我無法理解使用DP的解決方案。
設N
是行數,M
是列數。
你可以嘗試用狀態動態規劃方法: dp(int row_idx, int col_idx, int visited_msk)
其中visited_msk
現在代表參觀細胞達到一個整數(即用於matrix[i][j]
在visited_msk
的ID將i*M + j
你的DP裏面,你會迭代相鄰的8個單元(如果它們在邊界內),並且僅當絕對差大於3並且單元未被像這樣訪問時才從當前單元調用DP:
讓新索引在面膜是new_idx = new_row_idx * M + new_col_idx
在內部循環,則情況將是這樣的:
if(abs(matrix[row_idx][col_idx] - matrix[new_row_idx][new_col_idx]) > 3 && !((visited_msk >> new_idx) & 1)) {
result = max(result, dp(new_row_idx, new_col_idx, visited_msk | (1<<new_idx)) + 1);
}
這種方法的順序是O(2 ^(N * M)* N * M * 8),所以這將是細如果N * M(網格大小)是< = 15。
您能否詳細解答一下答案?我找不到 –
visited_msk將是一個整數,我應該保留visited_msk的列表以跟蹤訪問項目的特定迭代嗎?當我完成訪問特定元素的所有可能路徑時,我找到最大值,並從列表中移除該元素的visited_msk,並使用下一個元素繼續它。 –
'visited_msk'是普通的整數,但我們將它作爲布爾數組處理。 編程語言中的'signed int'由32位組成(1位爲符號)。例如:5表示爲101 因此,如果將int視爲數組,則5是一個數組,其中元素0和2設置爲1(已訪問),其他位不設置,如果要設置索引位3到1你需要做這個'(0101 | 1000)= 1101',這意味着ORing 5與8即'5 | (1 <<3)' ->'msk |(1 << idx)'。也是'(msk >> idx)&1)'檢查位是否被設置爲1或0.有關位掩碼的更多信息,請參閱http://stackoverflow.com/questions/ 10493411 /什麼,是位掩碼 – khairy
此問題[看起來是NP-hard](https://en.wikipedia.org/wiki/Longest_path_problem)。 –