校賽 填充數字串 分析

2021-05-22 13:42:04 字數 1391 閱讀 5993

填充數字串

problem description

小明最近對數字很感興趣,整天對著數字發呆,今天想到乙個奇妙的問題很興奮,但百思不得其解,現在他向你尋求幫助。

給定兩個只包含數字[0..9]的數字串(不含前導0),求使用第二個數字串中的數字插入到第乙個數字串中,使得插入後形成的第乙個數字串中每兩個相鄰數字間的差值絕對值的和最大。

注意:第二個數字串中的每個數字只能使用一次;不能插入到第乙個數字串的第乙個位置和最後乙個位置,並且第乙個數字串中每兩個數字間只能插入乙個數字。

input

第一行乙個數字t(t<=100),表示測試資料組數。

接下來2*t行,每兩行代表一組測試資料。

第一行代表第乙個數字串,數字串的長度為2..1000。

第二行代表第二個數字串,數字串的長度為1..1000。

output

對於每組測試資料,輸出一行所求的最大和。

sample input

sample output

完畢。個人認為這是一道dp,但是由於資料規模有點大,我寫的**tle了。現在還在優化我的**。

我的思路是這樣的:

1、先求得第一數字串中相鄰數字間的差值絕對值,記錄在origin中。

2、之後將第二個數字串中的第i個數字依次插入到第乙個數字串的所有合法位置,求的插入後的淨增長值temp,顯然該串的長度和original的長度一樣。求的從origin中每個位置到當前一步的最大值。

其中建立個標記變數mark,其中的值這樣定義:mark[k]的值是乙個二進位制數對應的十進位制數,每一位對應第乙個數字串中的乙個可插入位。mark[k]表示map[k]中各次轉移在第乙個數字串中的插入位置。

如果函式filledmark( mark[k], j, total )值為1的話,表示可以j位填充,否則表示j位已經填充過了。其中total位第乙個數字串可插入位的長度。

再到使得map[k]最大的可填入temp[j]後,fillmark( mark[k], j, total )

3、更新map[k]

4、重複2、3,直到第二個數字串中的全部數字插入完畢。

5、遍歷map,找到最大值

發現這是乙個o(t * lenb * lena ^ 2)事件複雜度的**……囧

經過分析,時間主要是浪費在了找滿足條件的j上了,我想到的一步優化是:將temp降序快排一下,這樣在此查詢滿足條件的j時就會快一些,最壞的情況下,還是o(t * lenb * lena ^ 2),幸運的話可以是o(t * lenb * lena * lg(lena))。這樣就從100*1000*1000*1000降到了100*1000*1000*3。

可能分析的不對,還望高手請教。

**見我的csdn部落格  http://blog.csdn.net/clhmw/archive/2010/05/17/5602110.aspx

Wannafly挑戰賽15 D 數字串 區間逆序對

乙個只含數字的字串,q次操作,每次操作將第i位數字改為x,每次操作後,統計長度在 l,r 之間且首數字大於尾數字的子串的個數。第一行乙個只含數字的字串 第二行3個整數q,l,r 接下來q行,每行兩個整數i,x。輸出q行,每行乙個整數,表示長度在 l,r 之間且首數字大於尾數字的子串的個數。示例1 5...

Wannafly挑戰賽15 D 數字串 線段樹

乙個只含數字的字串,q次操作,每次操作將第i位數字改為x,每次操作後,統計長度在 l,r 之間且首數字大於尾數字的子串的個數。第一行乙個只含數字的字串 第二行3個整數q,l,r 接下來q行,每行兩個整數i,x。輸出q行,每行乙個整數,表示長度在 l,r 之間且首數字大於尾數字的子串的個數。題解 更改...

樹狀陣列 牛客挑戰賽15D 數字串

最近做了不少樹狀陣列的題目,不得不感嘆,這真是乙個優美的資料結構。起碼可以簡潔高效地求出陣列字首和。最近常常碰到的是求一段區間內大於或小於某個數的個數。如果數字範圍較大,但不要求修改的話,可以用樹狀陣列存離散化後的數的大小。比如 1 2 4 4 6 7,離散化 1 2 3 3 4 5,統計個數 0 ...