填充數字串
Problem Description
小明最近對數字很感興趣,整天對着數字發呆,今天想到一個奇妙的問題很興奮,但百思不得其解,現在他向你尋求幫助。
給定兩個只包含數字[0..9]的數字串(不含前導0),求使用第二個數字串中的數字插入到第一個數字串中,使得插入後形成的第一個數字串中每兩個相鄰數字間的差值絕對值的和最大。
注意:第二個數字串中的每個數字只能使用一次;不能插入到第一個數字串的第一個位置和最後一個位置,並且第一個數字串中每兩個數字間只能插入一個數字。
Input
第一行一個數字T(T<=100),表示測試數據組數。
接下來2*T行,每兩行代表一組測試數據。
第一行代表第一個數字串,數字串的長度爲2..1000。
第二行代表第二個數字串,數字串的長度爲1..1000。
Output
對於每組測試數據,輸出一行所求的最大和。
Sample Input
3
51
4
51
9
123
4
Sample Output
4
12
6
完畢。個人認爲這是一道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