[USACO Training] Section 1.4

这一章的主题是枚举。

TEXT Search Techniques

搜索      时间  空间      何时使用
DFS     O(c^k)  O(k)    必须搜索整棵树,知道解所在的层数,或者不需要层次最浅的解
BFS     O(c^d)  O(c^d)  知道解所在的层次很浅,或者需要最浅的解
DFS+ID  O(c^d)  O(d)    想要BFS,却没有足够的空间,并且能承受以时间换空间
c是每层做出的选择的数目
d是解的深度
k是搜索的深度
d <= k

PROB Arithmetic Progressions

给定N、M,寻找所有长度为N的共差为正整数的等差数列,每一项均能表示成p^2+q^2,0<=p, q<=M。3<=N<=25,1<=M<=250。

百度一下,找“Arithmetic Progressions”的中文翻译,无意中瞥到一个题解,说用最笨的方法AC了。于是我一直在想什么方法最笨……

首先打一个表,把p^2+q^2枚举出来,存到STL map里。map维护数到以该数结尾的合法等差数列的最大长度的映射。每次搜索公差为d的等差数列(一是因为这样方便,二是因为题目要求以公差为第一关键字排序输出),遍历这个map递推即可。用最大的数据测试了一下,等了好长时间都没出解。题目中有一个条件:数列的个数不超过10000。也许数据是专门构造的,我这样可行?于是加上找到10000个就退出。提交,TLE。

本机测试了一下,要10多秒。开O2,4秒多,看起来可以卡过去的样子,然而这个OJ不开O2……据说O2能大幅度提升STL的性能,所以可能是map比较慢。换成排序+二分。快了一些,可是还是会T。突然醒悟:“前一项”在顺序遍历时具备单调性!所以两个指针扫一遍即可,砍掉一个log。AC。

看ANALYSIS。我好像忽略了本题p^2+q^2值域很小这个特性……测了一下第2个解答,为什么人家的复杂度比我差跑得却比我快?QAQ

/*
ID: chrt2001
PROG: ariprog
LANG: C++
*/
#include 
#include 

你可能感兴趣的:(枚举法)