做了几道题让我想起一个问题,就是重叠子问题这个思想。
记得动态规划优化问题的两个要素就是,最优子结构和重叠子问题。
关于重叠子问题的优化,就是这些子问题可能多次用到,多次计算,所以可以事先计算了,然后用到的时候查表。
比如之前的codejam的B题,里面就有重叠子问题,小数据的时候,一般都可以写出,而大数据的时候你再用一般的方法,程序跑出结果的时间就非常慢,而如果事先预处理,将一定范围的值先计算出来,需要的时候查表即可,速度快了很多。
再如UVa 253题,你可以根据每次输入进行立方体的旋转变化,但如果你事先将24种状态都计算出来,后面只需要对24种状态查找即可。
我们常常考虑问题都是对一组数据来看,所以往往最初设计或实现的算法都是针对一组数据,稍加注意,就可以用重叠子问题来优化。有时候也能想到计算出一个大范围内的数据,但总会觉得计算得多了(比如,对于n=5,你只需要计算到5就行了,而你用打表的方法,可能是事先计算到n=10000;对于n=5这组数据来说,这样的确是计算得太多了,但从整体输入来说,省去了很多重复的计算)这样的方法,单从一组数据来看,肯定是直接计算该组数据来得快些,但从大规模输入数据,比如ACM题的大量输入来看,则优化了很多。有的直接是从O(n2)的复杂度降到了O(n);直观的对比,就是codejam的B题,用两种方法,效率差别太大。
之前自己已经有这个思想了,太久没做题,好像忘了,刚刚做UVa 253 自己突然想到了。借此提醒一下自己。