题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1136 http://poj.org/problem?id=2533
题目大意:RT
题目思路:
maxlen[j]表示,到j位置,最长的上升子序列的长度。时间复杂度O(N^2),数据范围是1000
参考解题报告:http://www.slyar.com/blog/longest-ordered-subsequence.html
zoj:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 #include <cctype> 6 #include <stack> 7 #include <queue> 8 #include <deque> 9 #include <map> 10 #include <set> 11 #include <vector> 12 #include <cmath> 13 #include <algorithm> 14 #define lson l, m, rt<<1 15 #define rson m+1, r, rt<<1|1 16 using namespace std; 17 typedef long long int LL; 18 const int MAXN = 0x7fffffff; 19 const int MINN = -0x7fffffff; 20 const double eps = 1e-9; 21 const int dir[8][2] = {{0,1},{1,0},{0,-1},{-1,0},{-1,1}, 22 {1,1},{1,-1},{-1,-1}}; 23 24 int str[1000], maxlen[1001], p[1001]; 25 int main(void){ 26 #ifdef LOCAL 27 freopen("lis.in", "r", stdin); 28 #endif 29 int n, i, j, tmp, T; 30 scanf("%d", &T); 31 while (T--) { 32 scanf("%d", &n); 33 for (i = 0; i < n; ++i) { 34 scanf("%d", str+i); 35 } 36 memset(maxlen, 0, sizeof(maxlen)); 37 maxlen[0] = 1; 38 for (i = 1; i < n; ++i) { 39 tmp = 0; 40 for (j = 0; j < i; ++j) { 41 if (str[j] < str[i]) { 42 if (tmp < maxlen[j]) { 43 tmp = maxlen[j]; 44 } 45 } 46 } 47 maxlen[i] = tmp + 1; 48 } 49 tmp = -1; 50 for (i = 0; i < n; ++i) { 51 if (tmp < maxlen[i]) { 52 tmp = maxlen[i]; 53 } 54 } 55 printf("%d\n", tmp); 56 if (T) printf("\n"); 57 } 58 59 return 0; 60 }
貌似有的时候zoj也会对
1 #ifndef ONLINE_JUDGE 2 freopen(".in", "r", stdin); 3 #endif
报CE……所以,还是用#define LOCAL吧……
poj
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 #include <cctype> 6 #include <stack> 7 #include <queue> 8 #include <deque> 9 #include <map> 10 #include <set> 11 #include <vector> 12 #include <cmath> 13 #include <algorithm> 14 #define lson l, m, rt<<1 15 #define rson m+1, r, rt<<1|1 16 using namespace std; 17 typedef long long int LL; 18 const int MAXN = 0x7fffffff; 19 const int MINN = -0x7fffffff; 20 const double eps = 1e-9; 21 const int dir[8][2] = {{0,1},{1,0},{0,-1},{-1,0},{-1,1}, 22 {1,1},{1,-1},{-1,-1}}; 23 24 int str[1000], maxlen[1001], p[1001]; 25 int main(void){ 26 #ifdef LOCAL 27 freopen("lis.in", "r", stdin); 28 #endif 29 int n, i, j, tmp, T; 30 // scanf("%d", &T); 31 //while (T--) 32 { 33 scanf("%d", &n); 34 for (i = 0; i < n; ++i) { 35 scanf("%d", str+i); 36 } 37 memset(maxlen, 0, sizeof(maxlen)); 38 maxlen[0] = 1; 39 for (i = 1; i < n; ++i) { 40 tmp = 0; 41 for (j = 0; j < i; ++j) { 42 if (str[j] < str[i]) { 43 if (tmp < maxlen[j]) { 44 tmp = maxlen[j]; 45 } 46 } 47 } 48 maxlen[i] = tmp + 1; 49 } 50 tmp = -1; 51 for (i = 0; i < n; ++i) { 52 if (tmp < maxlen[i]) { 53 tmp = maxlen[i]; 54 } 55 } 56 printf("%d\n", tmp); 57 //if (T) printf("\n"); 58 } 59 60 return 0; 61 }
貌似还有一种nlogn的方法:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 #include <cctype> 6 #include <stack> 7 #include <queue> 8 #include <deque> 9 #include <map> 10 #include <set> 11 #include <vector> 12 #include <cmath> 13 #include <algorithm> 14 #define lson l, m, rt<<1 15 #define rson m+1, r, rt<<1|1 16 using namespace std; 17 typedef long long int LL; 18 const int MAXN = 0x7fffffff; 19 const int MINN = -0x7fffffff; 20 const double eps = 1e-9; 21 const int dir[8][2] = {{0,1},{1,0},{0,-1},{-1,0},{-1,1}, 22 {1,1},{1,-1},{-1,-1}}; 23 const int Size = 1009; 24 int Stack[Size]; 25 void bin(int tmp, int top) { 26 int low = 1, high = top, mid; 27 while (low <= high) { 28 mid = (high + low) / 2; 29 if (tmp > Stack[mid]) { 30 low = mid + 1; 31 } else { 32 high = mid - 1; 33 } 34 } 35 Stack[low] = tmp; 36 } 37 int main(void){ 38 #ifdef LOCAL 39 freopen("2533.in", "r", stdin); 40 #endif 41 int i, j, n, top, tmp; 42 scanf("%d", &n); 43 Stack[0] = -1; top = 0; 44 for (i = 0; i < n; ++i) { 45 scanf("%d", &tmp); 46 if (tmp > Stack[top]) { 47 Stack[++top] = tmp; 48 } else { 49 bin(tmp, top); 50 /* 51 int low = 1, high = top, mid; 52 while (low <= high) { 53 mid = (low + high) / 2; 54 if (tmp > Stack[mid]) { 55 low = mid + 1; 56 } else { 57 high = mid - 1; 58 } 59 } 60 Stack[low] = tmp; 61 */ 62 } 63 } 64 printf("%d\n", top); 65 66 return 0; 67 }
这个方法虽然最终不能求出最长的上升子序列,但是可以求出最长上升子序列的长度。