zoj2136 && poj2533 Longest Ordered Subsequence ——最长上升子序列经典DP

题目链接: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 }

这个方法虽然最终不能求出最长的上升子序列,但是可以求出最长上升子序列的长度。

原文地址:https://www.cnblogs.com/liuxueyang/p/3081587.html