最长有序子序列—动态规划算法
動態規劃使用范圍:(http://baike.baidu.com/view/28146.htm)
任何思想方法都有一定的局限性,超出了特定條件,它就失去了作用。同樣,動態規劃也并不是萬能的。適用動態規劃的問題必須滿足最優化原理和無后效性。
1.最優化原理(最優子結構性質) 最優化原理可這樣闡述:一個最優化策略具有這樣的性質,不論過去狀態和決策如何,對前面的決策所形成的狀態而言,余下的諸決策必須構成最優策略。簡而言之,一個最優化策略的子策略總是最優的。一個問題滿足最優化原理又稱其具有最優子結構性質。
2.無后效性 將各階段按照一定的次序排列好之后,對于某個給定的階段狀態,它以前各階段的狀態無法直接影響它未來的決策,而只能通過當前的這個狀態。換句話說,每個狀態都是過去歷史的一個完整總結。這就是無后向性,又稱為無后效性。
3.子問題的重疊性 動態規劃將原來具有指數級復雜度的搜索算法改進成了具有多項式時間的算法。其中的關鍵在于解決冗余,這是動態規劃算法的根本目的。 動態規劃實質上是一種以空間換時間的技術,它在實現的過程中,不得不存儲產生過程中的各種狀態,所以它的空間復雜度要大于其它的算法。
動態規劃思想:
?????? 如果各個子問題不是獨立的,不同的子問題的個數只是多項式量級,如果我們能夠保存已經解決的子問題的答案,而在需要的時候再找出已求得的答案,這樣就可以避免大量的重復計算。由此而來的基本思路是,用一個表記錄所有已解決的子問題的答案,不管該問題以后是否被用到,只要它被計算過,就將其結果填入表中。
時間復雜度為O(n^2),算法原理:
數組a[]為待處理數組
f[]用于記錄a[]數組中,以對應位置數據為結尾的最長有序序列長度
p[]用于記錄a[]數組中,以對應位置數據為結尾的前一個數據位置
使用position記錄最大長度位置
以a[]={1,4,7,2,5,8,3,6,9},計算最長遞增有序子序列為例
初始化f[]={1, 1, 1, 1, 1, 1, 1,1,1},p[]={0,1,2,3,4,5,6,7,8}
計算f[i]時,f[i]=max(f[j]+1) ,(其中,a[i]>a[j],i>j>=0),意思是以a[i]為結尾,找出在a[i]前比a[i]小的數據中以該數據為結尾的最大有序子序列長度max(f[j]),則以a[i]結尾的最大有序子序列長度為max(f[j])+1。計算同時定義p[i]=j,標志a[i]為結尾的最長子序列的前一個數據a[j]的位置。同時判斷此時最大長度a[i]是否比當前最大長度max大,如果a[i]更大則更新position
a[]={1,4,7,2,5,8,3,6,9}
i=0?? f[]={1,1,1,1,1,1,1,1,1},? p[]={0,1,2,3,4,5,6,7,8}
i=1?? f[]={1,2,1,1,1,1,1,1,1},? p[]={0,0,2,3,4,5,6,7,8}? 4>1,所以最大長度為2,position=1
i=2?? f[]={1,2,3,1,1,1,1,1,1},? p[]={0,0,1,3,4,5,6,7,8}? 7>4,7>1 其中4結尾的長度為2,所以最大長度為3,position=2
i=3?? f[]={1,2,3,2,1,1,1,1,1},? p[]={0,0,1,0,4,5,6,7,8}? 2>1 所以最大長度為2
i=4?? f[]={1,2,3,2,3,1,1,1,1}, ?p[]={0,0,1,0,1,5,6,7,8}? 5>1,5>4,5>2,其中以4結尾的長度為2,所以最大長度為3
i=5?? f[]={1,2,3,2,3,4,1,1,1},? p[]={0,0,1,0,1,2,6,7,8}? 8比前面的數據都大,所以最大長度為4,position=5
i=6?? f[]={1,2,3,2,3,4,3,1,1},? p[]={0,0,1,0,1,2,3,7,8}??3>1,3>2,其中以2結尾的長度為2,所以最大長度為3
i=7???f[]={1,2,3,2,3,4,3,4,1},? p[]={0,0,1,0,1,2,3,4,8}? 6>1,6>4,6>2,6>5,6>3,其中以5結尾長度為3,所以最大長度為4
i=8? ?f[]={1,2,3,2,3,4,3,4,5},? p[]={0,0,1,0,1,2,3,4,5}? 9比前面數據都大,所以最大長度為5,position=8
在對所有a中元素循環過后,通過max記錄下最后數據位置,以及p記錄的前一個數據的位置,可以遞歸求出LIS
代碼如下:
[cpp] view plaincopy?又如hdoj中的 1160 FatMouse's Speed
Problem Description FatMouse believes that the fatter a mouse is, the faster it runs. To disprove this, you want to take the data on a collection of mice and put as large a subset of this data as possible into a sequence so that the weights are increasing, but the speeds are decreasing.
?
The data for a particular mouse will consist of a pair of integers: the first representing its size in grams and the second representing its speed in centimeters per second. Both integers are between 1 and 10000. The data in each test case will contain information for at most 1000 mice.
Two mice may have the same weight, the same speed, or even the same weight and speed.
?
W[m[1]] < W[m[2]] < ... < W[m[n]]
and
S[m[1]] > S[m[2]] > ... > S[m[n]]
In order for the answer to be correct, n should be as large as possible.
All inequalities are strict: weights must be strictly increasing, and speeds must be strictly decreasing. There may be many correct outputs for a given input, your program only needs to find one.
?
?
?
代碼如下:
[cpp] view plaincopy總結
以上是生活随笔為你收集整理的最长有序子序列—动态规划算法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 位运算实例(一):判断奇偶性
- 下一篇: ACM 网址和一些建议