原 最長上公升子串行 動態規劃

2021-09-06 06:27:13 字數 1346 閱讀 8695

這個是用動態規劃做的一道題,先學習一下動態規劃的概念吧。  

用動態規劃解題,就是要把問題分解為乙個個子問題,對子問題進行求解,而子問題又可以繼續進行分解,直到一定小的規模。

dp與遞迴類似,但遞迴會導致重複計算,而用dp每次計算後的子問題的解都會被儲存起來,從而避免了重複計算,保證了效率,比如本題用maxlen儲存每個狀態值

對於每組與子問題有關係的變數,我們對他們進行取值,稱之為子問題的「狀態」,而「狀態」的值就是該子問題的解。

定義出什麼是「狀態」、得到「狀態」的值後,就要找出不同狀態之間的遷移關係,即通過乙個狀態求另乙個狀態的值,往往有乙個遞推公式,我們把這個遞推公式成為狀態轉移方程。

現在反過來看這道題:

輸入資料 

輸入的第一行是序列的長度n (1 <= n <= 1000)。第二行給出序列中的 n 個整數,這些

整數的取值範圍都在0 到10000。 

輸出要求 

最長上公升子串行的長度。 

輸入樣例 

7 1 7 3 5 9 4 8 

輸出樣例  4

問題分析:

怎麼分解成子問題呢?我們把「以a

k為終點的序列的最長上公升子串行的長度」作為問題的子問題,其中k = 1,2,3......n .

這樣就把問題分解為n個子問題,只要我們把這n個子問題解決了,從中找出解值最大的即為原問題的解

怎麼求狀態轉移方程呢?顯然當k = 1的時候,maxlen[k] = 1;而通過k=1這個狀態求別的狀態的轉移方程則可以寫成:

maxlen[k] = (max(maxlen[i]),i = 1,2,3,....,k-1&& str[i] < str[k]) + 1;

這個方程的含義是:要求以a

k為終點的序列的最長上公升子串行的長度,只要算出以滿足條件的a

k左邊的某乙個數為終點的序列的最長上公升子串行的長度 再 加上a

k這個數,即長度再加1即可,得到的這樣乙個序列必定是包含a

k的這裡要充分理解遞迴的思想(雖然這裡並不用到遞迴函式)

1 #include 2 using namespace std;

3 4 int str[1001];

5 int maxlen[1001];

6 int p[1001];

7 8 int main()

9 23 maxlen[i] = temp + 1;

24 }

25 int temp = -1;

26 for(int i = 1;i < n ;i++)

30 cout << temp;

31 }

最長上公升子串行 (動態規劃)

描述乙個數的序列 bi,當 b1 b2 bs的時候,我們稱這個序列是上公升的。對於給定的乙個序列 a1,a2,an 我們可以得到一些上公升的子串行 ai1,ai2,aik 這裡1 i1 i2 ik n。比如,對於序列 1,7,3,5,9,4,8 有它的一些上公升子串行,如 1,7 3,4,8 等等。...

最長上公升子串行(動態規劃)

描述 乙個數的序列bi,當b1 b2 bs的時候,我們稱這個序列是上公升的。對於給定的乙個序列 a1,a2,an 我們可以得到一些上公升的子串行 ai1,ai2,aik 這裡1 i1 i2 ik n。比如,對於序列 1,7,3,5,9,4,8 有它的一些上公升子串行,如 1,7 3,4,8 等等。這...

最長上公升子串行(動態規劃)

給定乙個無序的整數陣列,找到其中最長上公升子串行的長度。示例 輸入 10,9,2,5,3,7,101,18 輸出 4 解釋 最長的上公升子串行是 2,3,7,101 它的長度是 4。說明 可能會有多種最長上公升子串行的組合,你只需要輸出對應的長度即可。你演算法的時間複雜度應該為 o n2 原題跳轉鏈...