我有一个像这样的矩阵 - >
1 6 2
8 3 7
4 9 5
你可以向任何方向,在对角线上向左下方,你必须找到最长的子序列,你可以选择序列中的下一个数字,使其绝对差值大于3.
与上面的情况类似,最长的子序列是1->6->2->7->3->8->4->9->5
。
我能为它写一个强力代码,找到最长的序列,就像找到第一个数字,第二个数字等的最长序列一样。并返回具有最大计数的那个。
我是DP新手。有没有其他方法可以通过使用DP来解决这个问题?我无法理解使用DP的解决方案。
答案 0 :(得分:3)
让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:< / p>
让掩码中的新索引为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,它将会很好。