题目大意:
给出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”!!!
代码: