网格中的有效方法

Efficient approach in the grid

本文关键字:方法 有效 网格      更新时间:2023-10-16

问题:我们必须用集合S中的字符填充大小为m*n的二维网格,使得生成的网格中不同的子矩阵的数量接近给定的数字k。
这个问题来源于http://www.codechef.com/JULY14/problems/GERALD09

限制:
1 & lt; = n, m<16
1<=k <=m*n*m*n
S | | = 4
时间限制=0.1秒

假设:如果两个子矩阵不具有相同的维数,或者至少有一对对应位置的字符不匹配,则它们是不同的。

我的方法:我们可以从随机网格和循环开始,同时找到可接受的解决方案,在每次迭代中,我们可以根据当前状态增加/减少随机性(但我们可以停留在局部最优状态)。

但问题是我不知道有效的方法来计算子网格中不同子矩阵的数量。我尝试了哈希计数,它非常快(O(n2m2)*为子网格生成/搜索哈希值的成本)。但是由于哈希值的冲突,这种方法不能给出确切的答案,即使在使用@Vaughn Cato的评论纠正它之后,我也可以进行15-25次迭代来寻找最佳状态,这还不够。

最近,我了解到模拟退火可以用来解决这类问题。
http://www.theprojectspot.com/tutorial-post/simulated-annealing-algorithm-for-beginners/6
我正在寻找解决这个优化问题的有效方法。

我想他们会在某个时候发表一篇社论,但对于这个特殊的问题,这里有一个可能的想法:

我局部生成了特定nm的所有可能的子矩阵数。对于n=m=3,我从81中只得到11。对于n=3,m=4,我从可能的144值中只得到19。更重要的是,当我生成这些值时,我一开始就获得了所有19可能的选项——在263000矩阵从可能的16M矩阵中剔除之后,我已经拥有了它们。(按字典顺序生成)

因此,我认为,一个可能的解决方案可能是预先计算尽可能多的K的不同值,可以为给定的nm实现,保存随机生成器的种子或以其他方式,例如每个n-m-k三元组需要O(1)个字符,对于特定的测试用例,只需检查两个相邻的值-首先k大于和小于给定。

更重要的是,由于K的可能值并不多,也可以用其他方式生成:给定nxm表的K的所有可能值,以及相应的表,我们只能通过下一行的值进行回溯,并尝试获得nx(m+1)表的K的所有不同值的所有可能矩阵。