第十一屆藍橋杯 字串排序(DP)

2021-10-14 16:23:32 字數 1993 閱讀 6488

小藍最近學習了一些排序演算法,其中氣泡排序讓他印象深刻。

在氣泡排序中,每次只能交換相鄰的兩個元素。小藍發現,如果對乙個字串中的字元排序,只允許交換相鄰的兩個字元,則在所有可能的排序方案中,氣泡排序的總交換次數是最少的。

例如,對於字串lan

lanla

n排序,只需要1

11次交換。對於字串 qia

oqiao

qiao

排序,總共需要 4

44 次交換。

小藍找到了很多字串試圖排序,他恰巧碰到乙個字串,需要 v

vv 次交換,可是他忘了把這個字串記下來,現在找不到了。

小藍的幸運數字是v

vv ,他想找到乙個只包含小寫英文本母的字串,對這個串中的字元進行氣泡排序,正好需要v

vv次交換。請幫助小藍找乙個這樣的字串。如果可能找到多個,請告訴小藍最短的那個。如果最短的仍然有多個,請告訴小藍字典序最小的那個。請注意字串中可以包含相同的字元。

氣泡排序的交換次數——序列中逆序對的個數。

在滿**換次數v的前提下,要求最短的序列。因為確定長度下的序列,逆序對個數的最大值是確定的,那麼只需找到第乙個逆序對個數》=v的序列長度,該長度即為所要求的最短序列的長度。

字典序最小,在已知序列長度下,我們可以從序列的第乙個(開頭)字母開始往後列舉,每次從』a』~'z』的順序列舉每個字母,直到找到第乙個滿足以該列舉的字母為開頭的序列的最大逆序對個數 + 已經確定的逆序對個數 >= v,才繼續往後列舉下乙個字母的值。

① 求最短序列長度

在確定的長度下,要求序列的逆序對個數的最大值,那麼序列的第 i 個字母一定要 >= 第 i + 1 個字母(可以用反證法證明)

② 求字典序最小的序列

根據①的分析,可以知道每次的列舉應該改為從』a』~last,last為序列中的上乙個字母。

重點就是要算出以該列舉的字母為開頭的序列的最大逆序對個數,這裡採用dp的方法,並且將該步和①的計算放在一起。

分析方法:閆氏dp分析法

;//chcnt[i][j]記錄第i個位置取字母j+'a'的逆序對最大值

int chcnt[n][30

];//mlen[i]記錄每個位置的最大值

int mlen[n]

;voiddp(

) m =

max(m, chcnt[i]

[j]);}

mlen[i]

= m;}}

intmain()

int curr =0;

//用於記錄逆序值

int same =1;

//記錄字尾中有多少個相同字母

char last =

'z'+1;

//記錄上乙個字母是什麼

第十一屆藍橋杯

問題描述 小藍要為一條街的住戶製作門牌號。這條街一共有 2020 位住戶,門牌號從 1 到 2020 編號。小藍製作門牌的方法是先製作 0 到 9 這幾個數字字元,最後根據需要將字 符貼上到門牌上,例如門牌 1017 需要依次貼上字元 1 0 1 7,即需要 1 個 字元 0,2 個字元 1,1 個...

第十一屆藍橋杯 字串編碼

問題描述 小明發明了一種給由全大寫字母組成的字串編碼的方法。對於每乙個大寫字母,小明將它轉換成它在 26 個英文本母中序號,即 a 1,b 2,z 26。這樣乙個字串就能被轉化成乙個數字序列 比如abcxyz 123242526。現在給定乙個轉換後的數字序列,小明想還原出原本的字串。當然這樣的還原有...

第十一屆藍橋杯 矩陣

問題描述 把 1 2020 放在 2 1010 的矩陣裡。要求同一行中右邊的比左邊大,同一列中下邊的比上邊的大。一共有多少種方案?答案很大,你只需要給出方案數除以 2020 的餘數即可。答案提交 這是一道結果填空題,你只需要算出結果後提交即可。本題的結果為乙個整數,在提交答案時只填寫這個整數,填寫多...