题目
给定一个 n × m n \times m n×m 的矩阵,行数和列数都不超过 20,其中有些格子可以选,有些格子不能选。现在你需要从中选出尽可能多的格子,且保证选出的所有格子之间不相邻(没有公共边)。
例如下面这个矩阵( 2 × 3 2 \times 3 2×3的矩阵)
1 1 1
0 1 0
最多可选 33 个互不相邻的格子,方案如下(选中的位置标记为x):
x 1 x
0 x 0
解法详解
我们可以自上而下一行一行选择格子。在选择格子的过程中,只和上一行选择的方案有关,所以我们可以将“当前放到第几行,当前行的选择方案”作为状态进行状态压缩动态规划。
一行里被选择的格子可以看作一个集合,我们要将这个集合压缩为一个二进制数,如果选了就即将当前位设为1,否则没选为0.比如,对于一个3列的矩阵,如果当前行的状态是 ( 5 ) 10 = ( 101 ) 2 (5)_{10}=(101)_{2} (5)10=(101)2,代表当前行选择了第一个和第三个各自。类似地,如果当前行的状态时 ( 6 ) 10 = ( 110 ) 2 (6)_{10}=(110)_{2} (6)10=(110)2,代表,当前行选择了第一个和第二个格子那么意味着(当然由于计算顺序的缘故,我们通常会将 ( 110 ) 2 (110)_{2} (110)