天天看點

頁【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”!!!

代碼: