题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=17&page=show_problem&problem=1475
Dynamic Programming. 最长增长子序列。推荐一个链接:http://www.cnblogs.com/liyukuneed/archive/2013/05/26/3090402.html。按照链接里的方法三(其他的会有TLE - time limit exceed),求得以ith element为尾的最长增长子序列的长度,以及以ith element为始的最长递减子序列的长度。代码如下:
1 #include <iostream> 2 #include <math.h> 3 #include <stdio.h> 4 #include <cstdio> 5 #include <algorithm> 6 #include <string.h> 7 #include <string> 8 #include <sstream> 9 #include <cstring> 10 #include <queue> 11 #include <vector> 12 #include <functional> 13 #include <cmath> 14 #include <set> 15 #define SCF(a) scanf("%d", &a) 16 #define IN(a) cin>>a 17 #define FOR(i, a, b) for(int i=a;i<b;i++) 18 typedef long long Int; 19 using namespace std; 20 21 int inLen[10005], deLen[10005]; 22 23 int BSI(int input[], int list[], int n, int right, int record[]) //increase sub-string 24 { 25 if (input[list[right]] < input[n]) 26 { 27 list[right + 1] = n; 28 record[n] = right + 1; 29 return right + 1; 30 } 31 32 if (input[list[1]] > input[n]) 33 { 34 list[1] = n; 35 record[n] = 1; 36 return right; 37 } 38 39 int l = 1, r = right; 40 int mid = 0; 41 42 while (l < r - 1) 43 { 44 mid = (l + r) / 2; 45 if (input[list[mid]] <= input[n]) 46 { 47 l = mid; 48 } 49 else 50 { 51 r = mid; 52 } 53 } 54 55 if (input[list[l]] < input[n]) 56 { 57 if (input[list[l + 1]] > input[n]) 58 { 59 list[l + 1] = n; 60 } 61 record[n] = l + 1; 62 } 63 else if (input[list[l]] == input[n]) 64 { 65 record[n] = l; 66 } 67 return right; 68 } 69 70 int main() 71 { 72 int N; 73 int input[10005]; 74 int increase[10005], decrease[10005]; 75 int inlen = 0, delen = 0; 76 while (SCF(N) != EOF) 77 { 78 FOR(i, 0, N) 79 { 80 SCF(input[i]); 81 } 82 83 increase[1] = 0; 84 inlen = 1; 85 inLen[0] = 1; 86 FOR(i, 1, N) 87 { 88 inlen = BSI(input, increase, i, inlen, inLen); 89 } 90 91 decrease[1] = N - 1; 92 delen = 1; 93 deLen[N - 1] = 1; 94 for (int i = N - 2; i >= 0; i--) 95 { 96 delen = BSI(input, decrease, i, delen, deLen); 97 } 98 99 int maxLen = 0; 100 FOR(i, 0, N) 101 { 102 if (min(inLen[i], deLen[i]) > maxLen) 103 maxLen = min(inLen[i], deLen[i]); 104 } 105 106 printf("%d\n", maxLen * 2 - 1); 107 } 108 return 0; 109 }