[Ural 1519]

Formula 1

插头DP

题意:给出一个最多12*12的地形描述,问有多少方式在其上建一条F1赛道。一条F1赛道为仅横竖相连且覆盖所有空地的一个环。

参考了陈丹琦的《基于连通性状态压缩的动态规划问题》,插头+轮廓线扫描。虽然论文已经给出了基本思路,但仍存在一些特殊情况,如:

应转变为

我用了很长时间才发现这一点。

实现方面,一开始打算全部用位运算,但发现存储的时候状态数太多,无法直接开大数组存,于是又转成3进制。每次更新下一个格点的状态值时,交换内存指针,根据相应内存位置标记来判断是否置0,这样就避免了每次对大数组进行memset。另外,使用了栈来非重复地保存各状态(仅当计数值为0时入栈),避免了每次扫描整个计数数组。

在ural上用VS 2010只能跑出0.6S左右的时间。瓶颈应该是慢在位向量和3进制间转换上面,但也没有想到太好的优化了……

ps:小小感慨一下,连这种问题都可以DP,实在是不可思议。