LIS (最长上升子序列)
LIS两种写法
O(n^2)
dp[i]表示以a[i]结尾的为LIS长度
1 #include <algorithm> 2 #include <iostream> 3 #include <cstdlib> 4 #include <cstring> 5 #include <cstdio> 6 #include <vector> 7 #include <cmath> 8 #include <ctime> 9 #include <list> 10 #include <set> 11 #include <map> 12 using namespace std; 13 typedef long long LL; 14 typedef pair <int, int> P; 15 const int N = 2e3 + 5; 16 int dp[N]; 17 int a[N]; 18 19 int main() 20 { 21 int n; 22 while(~scanf("%d", &n)) { 23 memset(dp, 0, sizeof(dp)); 24 int res = 0; 25 for(int i = 1; i <= n; ++i) { 26 scanf("%d", a + i); 27 dp[i] = 1; 28 for(int j = 1; j < i; ++j) { 29 if(a[i] > a[j]) 30 dp[i] = max(dp[i], dp[j] + 1); 31 } 32 res = max(res, dp[i]); 33 } 34 printf("%d\n", res); 35 } 36 return 0; 37 }
O(nlogn)
dp[i]表示LIS长度为i的最后一个元素
1 //#pragma comment(linker, "/STACK:102400000, 102400000") 2 #include <algorithm> 3 #include <iostream> 4 #include <cstdlib> 5 #include <cstring> 6 #include <cstdio> 7 #include <vector> 8 #include <cmath> 9 #include <ctime> 10 #include <list> 11 #include <set> 12 #include <map> 13 using namespace std; 14 typedef long long LL; 15 typedef pair <int, int> P; 16 const int N = 1e5 + 5; 17 int dp[N], a[N], inf = 1e6; 18 19 int main() 20 { 21 int n; 22 while(~scanf("%d", &n)) { 23 for(int i = 0; i <= n + 1; ++i) 24 dp[i] = inf; 25 for(int i = 1; i <= n; ++i) { 26 scanf("%d", a + i); 27 *lower_bound(dp, dp + n, a[i]) = a[i]; 28 } 29 printf("%d\n", lower_bound(dp, dp + n, inf) - dp); 30 } 31 return 0; 32 }