nyoj 题目17 单调递增最长子序列
单调递增最长子序列
时间限制:3000 ms | 内存限制:65535 KB
难度:4
- 描述
- 求一个字符串的最长递增子序列的长度
如:dabdbf最长递增子序列就是abdf,长度为4
- 输入
- 第一行一个整数0<n<20,表示有n个字符串要处理
随后的n行,每行有一个字符串,该字符串的长度不会超过10000 - 输出
- 输出字符串的最长递增子序列的长度
- 样例输入
-
3 aaa ababc abklmncdefg
- 样例输出
-
1 3 7
复习了利用二分搜索和额外空间解决最长递增子序列问题,最重要的是二分搜索的代码,如何找到某个新元素的位置。该元素比原来此位置的元素小,但和前后两个元素都不同。比前面的大,比后面的小。
代码如下1 #include <cstdio> 2 #include <cstring> 3 4 char s[10002]; 5 char tmp[10002]; 6 7 int find(int from, int end, int t) { 8 if(end == from) { 9 return end; 10 } 11 int mid = (from+end)/2; 12 if(tmp[mid] < s[t]) { 13 return find(mid+1,end,t); 14 } 15 else if(tmp[mid] >= s[t]) { 16 return find(from, mid,t); 17 } 18 else { 19 return mid; 20 } 21 } 22 int main(int argc, char const *argv[]) 23 { 24 int n; 25 scanf("%d",&n); 26 while(n--) { 27 scanf("%s",s); 28 tmp[0] = s[0]; 29 int len = strlen(s); 30 int ans = 0; 31 for(int i = 1; i < len; i++) { 32 if(s[i] > tmp[ans]) { 33 ans++; 34 tmp[ans] = s[i]; 35 } 36 else { 37 int p = find(0,ans,i); 38 tmp[p] = s[i]; 39 } 40 41 } 42 printf("%d\n", ans+1); 43 } 44 return 0; 45 }