最長不下降子串行(longest increasing subsequence)是動態規劃中的乙個非常經典的問題:
在乙個數字序列中,找到乙個最長的子串行(可以不連續),使得這個子串行是不下降(非遞減)的例如
a =
,它的最長不下降子串行是
,長度為 5。
對於這個問題,最簡單的辦法就是暴力列舉每種情況,即對於每個元素有取和不取兩種選擇,然後判斷這個序列是否為不下降序列。如果是不下降序列,就更新最大長度,但是很嚴峻的乙個問題這個時候時間複雜度就變成了o(2n)了。
我們介紹一下動態規劃的解法,時間複雜度為o(n2):
首先設定乙個陣列 dp ,令 dp[i] 代表以 a[i] 結尾的最長遞增子串行的長度,通過設定這個陣列,最長遞增子串行的長度就為 dp 中的最大值。
由於 dp[i] 是以 a[i] 作為結尾的最長不下降子串行的長度,因此只有兩種情況:
綜上,此時的狀態方程的遞推公式為
dp[i] = max(1, dp[j] + 1)
(j = 1, 2, ..., i -1 && a[j] <= a[i])
上面的狀態方程隱含了邊界:dp[i] = 1。顯然 dp[i] 只與小於 i 的 j 有關,因此只要讓 i 從小到大遍歷即可求出整個 dp 陣列。
此時,時間複雜度即為o(n2)。
**實現如下:
#include #include using namespace std;
const int maxn = 100;
int a[n], dp[n], n; // 序列和, dp陣列, 數字總數
int main() // 從 1 ~ n 編號
int ans = -1; // 記錄最大的 dp[i]
for(int i = 1; i < n; i++)
}ans = max(ans, dp[i]); // 確定當前結束的最長子序列的長度之後,比較
} printf("%d", ans);
return 0;
}
希望對大家有幫助。# 最長不下降子串行(lis)
最長不下降子串行(longest increasing subsequence)是動態規劃中的乙個非常經典的問題:
在乙個數字序列中,找到乙個最長的子串行(可以不連續),使得這個子串行是不下降(非遞減)的例如
a =
,它的最長不下降子串行是
,長度為 5。
對於這個問題,最簡單的辦法就是暴力列舉每種情況,即對於每個元素有取和不取兩種選擇,然後判斷這個序列是否為不下降序列。如果是不下降序列,就更新最大長度,但是很嚴峻的乙個問題這個時候時間複雜度就變成了o(2n)了。
我們介紹一下動態規劃的解法,時間複雜度為o(n2):
首先設定乙個陣列 dp ,令 dp[i] 代表以 a[i] 結尾的最長遞增子串行的長度,通過設定這個陣列,最長遞增子串行的長度就為 dp 中的最大值。
由於 dp[i] 是以 a[i] 作為結尾的最長不下降子串行的長度,因此只有兩種情況:
綜上,此時的狀態方程的遞推公式為
dp[i] = max(1, dp[j] + 1)
(j = 1, 2, ..., i -1 && a[j] <= a[i])
上面的狀態方程隱含了邊界:dp[i] = 1。顯然 dp[i] 只與小於 i 的 j 有關,因此只要讓 i 從小到大遍歷即可求出整個 dp 陣列。
此時,時間複雜度即為o(n2)。
**實現如下:
#include #include using namespace std;
const int maxn = 100;
int a[n], dp[n], n; // 序列和, dp陣列, 數字總數
int main() // 從 1 ~ n 編號
int ans = -1; // 記錄最大的 dp[i]
for(int i = 1; i < n; i++)
}ans = max(ans, dp[i]); // 確定當前結束的最長子序列的長度之後,比較
} printf("%d", ans);
return 0;
}
希望對大家有幫助。 動態規劃 最長不下降子串行LIS
找出一組資料中最長的不下降子串行的長度。1,連續情況。即必須要求子數列連續相依 1 2 3 1 2 7 9中的最長子串行為3 1,2,3 易得遞推公式 if f i f i 1 dp i dp i 1 1 else dp i 1 includeusing namespace std define m...
線性動態規劃 最長不下降子串行(LIS)
我們知道,遞推就是按照遞推公式不斷往前求解的乙個過程,對於當前,只有乙個狀態描述當前的值。若某些問題並非由乙個狀態而是由多個狀態不斷推導,那麼這種方法就是動態規劃,簡稱dp。動態規劃是運籌學的乙個分支,是將問題分解成各個階段,由相鄰的兩個階段根據狀態轉移方程推到求解的一種方法。所謂的線性動態規劃,就...
最長不下降子串行LIS
最長上公升子串行問題是解決很多問題的根本,它能幫助你理解二分的思想。考慮一下 對於乙個序列 n nn 請你查詢n nn中最長的子串行a aa,使得任意 i i j 時 a i a i a i a i a i a i 例如乙個長度為5 55的n nn 5553 331112 22444 顯然,它的最長...