天天看点

页【BFS】

题目大意:

给出nn(nn为3,5,7,9中的一个数)个在160至190的数字,每次可以把中间的数字放到最左边或最右边,求这个序列成为单调递增的最少次数。

InputInput

OutputOutput

思路:

哇!n≤9n≤9诶!好开心啊!贪心一定能过吧!

然而并不可以。。。

贪心有很大几率死循环。比如说:

左边三个数就永远死循环。

贪心代码:

贪心有可能无法搞定,但是如果DFS求出所有答案,再取最优值,肯定 没问题 TLE。

但是至少比0分好吧。

(仅仅是思路,代码未打完)

仔细一看,这题其实是要我们求最优解,那么自然会想到DP和BFS。由于数据规模小,所以大部分可能是BFS。

那么首先要解决BFS判重问题。贪心不用判重,但是BFS肯定要。自然而然的可以想到HASH,但是这里介绍另一种方法——mapmap库。

mapmap库是STLSTL中的一个。它的最常见用法是定义一个下标可以为任何类型(包括stringstring,charchar,doubledouble等等),范围巨大的数组。(不会MLE)

例如

表示定义一个下标为stringstring类型,变量类型为intint的无限大数组aa。定义了这个数组之后,就可以与正常用法一样使用它。例如:

然后既然mapmap是一个库,那么自然也要加上头文件

那么回到这道题,我们可以设定一个mapmap数组pp,即 map<int,int>pmap<int,int>p ,那么只要我们能把160到190的数字”压缩“成一位数,就好啦!(因为这样即使n=9n=9,9个数字连起来也就9位数,intint的范围是十位数,就不会爆)

那么应该怎么压缩呢?

可以用到离散化的思想,将最小的数对应1,次小的数对应2······最大的数对应nn,就把三位数压缩成了一位数。而且这里的离散化并不麻烦,n≤9n≤9,可以用O(n2)O(n2)的方法对应。

那么判重搞定了,接下来就是BFS的问题了。

不难想到,变化总数最多只有9!9!次,所以数组开到9!9!就可以了。

然后对于每一种情况,我们可以把中间的数字放到最左边或最右边,那么可以在移动前先判断移动后的结果是否会与之前的重复,重复就不移动,tail−−tail−−,不重复就移动,fatherfather数组更新,statestate记录答案。

移动后就判断是否单调,单调的话就递归输出答案,否则继续搜索。

注意:最终如果无法完成一定要输出”NoAnswerNoAnswer”!!!

代码: