給定乙個長度為n的數列,求數值嚴格單調遞增的子串行的長度最長是多少。
輸入格式
第一行包含整數n。
第二行包含n個整數,表示完整序列。
輸出格式
輸出乙個整數,表示最大長度。
資料範圍
1 ≤ n ≤ 1000,
−1 09
10^9
109 ≤ 數列中的數 ≤ 109
10^9
109輸入樣例:
7輸出樣例: 演算法13 1 2 1 8 5 6
(動態規劃) o(n
2n^2
n2)狀態表示:dp[i]表示從第乙個數字開始算,以a[i]結尾的最大的上公升序列。(以a[i]結尾的所有上公升序列中屬性為最大值的那乙個)
狀態計算(集合劃分):j∈(0,1,2, … , i - 1) , 在a[i] > a[j]時,
dp[i] = max(dp[i] , dp[i] + 1)。
有乙個邊界,若前面沒有比i小的,dp[i]為1(自己為結尾)。
最後在找dp[i]的最大值。
時間複雜度
o(n
2n^2
n2) 狀態數(n) * 轉移數(n)
c++ **
#include
using
namespace std;
const
int n =
1010
;int a[n]
, dp[n]
;int
main()
ans =
max(ans, dp[i]);
} cout << ans << endl;
return0;
}
演算法2
(動態規劃 + 二分) o(nlo
gn
nlog_n
nlogn
)狀態表示:f[i]表示長度為 i 的最長上公升子串行,末尾最小的數字。(長度為i的最長上公升子串行所有結尾中,結尾最小min的) 即長度為i的子串行末尾最小元素是什麼。
狀態計算:維護乙個陣列,使其為遞增序列,以 ans-1 為下標的數為該陣列的最大數,每次新輸入的數都放到該陣列中比該數大的第乙個數的位置,如果陣列中沒有比該數大的數則放在最後面。
f[i]一定以乙個單調遞增的陣列,所以可以用二分法來找第乙個大於或等於 x 的數字。
時間複雜度
o(n lo
gn
nlog_n
nlogn
) 狀態數(n) * 轉移數(log
nlogn
logn
)c++ **
#include
#include
using
namespace std;
const
int n =
1010
;int f[n]
;int
main()
else
if(x > f[ans-1]
) f[ans++
]= x;
} cout << ans << endl;
}
優化 最長上公升子串行 最長上公升子串行解題報告
給定乙個長度為n的數列 w n 求數值嚴格單調遞增的子串行的長度最長是多少。輸入格式 第一行包含整數n。第二行包含n個整數,表示完整序列。輸出格式 輸出乙個整數,表示最大長度。資料範圍 1 n 1000,1e9 數列中的數 1e9 輸入樣例 7 3 1 2 1 8 5 6 輸出樣例 4 includ...
最長上公升子串行問題
網上一大堆,說說思路吧,以4 2 6 3 1 5為例 逐個讀入數字,4 此時可能的佇列長度為1,最大值為4 4 2 由於2 4,此時佇列長度為1,最大值為2 4 2 6 6 2,佇列有2個,乙個長度為1,最大為2,乙個長度為2,最大為6 4 2 6 3 3 6,3 2,佇列有2個,乙個長度為1,最大...
最長上公升子串行問題
題型 poj 1631 問題描述 給出乙個陣列,求最長上公升子串行的長度。方法一 時間複雜度n 1000 思路 邊輸入邊處理,每次往陣列裡存,就替換這個數 就是所謂的二分法 include include include include using namespace std int a 40000...