題目大意:
給出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”!!!
代碼: