单调递增最长子序列
http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=17
- 描述
- 求一个字符串的最长递增子序列的长度
如:dabdbf最长递增子序列就是abdf,长度为4
- 输入
- 第一行一个整数0<n<20,表示有n个字符串要处理
随后的n行,每行有一个字符串,该字符串的长度不会超过10000 - 输出
- 输出字符串的最长递增子序列的长度
- 样例输入
-
3 aaa ababc abklmncdefg
- 样例输出
-
1 3 7
方法一:
#include <iostream> #include <cstring> using namespace std; string str; int dp[10005]; int main(){ int t; cin >> t; while(t--){ cin >> str; for(int i = 0; i < str.length(); i++){ dp[i] = 1; } int max = 0; for(int i = 0; i < str.length(); i++){ for(int j = 0; j < i; j++){ if(str[i] > str[j] && dp[j] + 1 > dp[i]){ dp[i] = dp[j] + 1; } } if(max < dp[i]){ max = dp[i]; } } cout << max << endl; } return 0; } 方法二:(for循环查找或二分查找:所求序列不一定正确,但长度正确) #include <iostream> #include <cstring> using namespace std; string str; int main(){ int t; cin >> t; while(t--){ int leng = 0; char ans[10005]; cin >> str; ans[0] = str[0]; for(int i = 1; i < str.length(); i++){ if(str[i] > ans[leng]){ ans[++leng] = str[i]; } else{ // for(int j = 0; j <= leng; j++){ //在ans中查找第一个比str[i]大或等的字母(即最小的最大值),将其替换掉 // if(str[i] <= ans[j]){ //可以用二分查找 // ans[j] = str[i]; // break; // } // } int x = lower_bound(ans, ans + leng, str[i]) - ans; //STL: 二分: t = lower_bound(s,s+top,m)-s; 返回值第一个大于等于m的数的地址,s是一个数组,top是查 //找长度,要减 s 得第一个大于等于m 的数的下标 //http://blog.csdn.net/zhongkeli/article/details/6883288 ans[x] = str[i]; } } cout << leng + 1 << endl; } return 0; }