#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;
const int MAXN = 10000+5;
int d[MAXN];
char a[MAXN];
int G[MAXN][MAXN];
int max(int a, int b){
if(a > b) return a;
else return b;
}
int dp(int i){
int& ans = d[i];
if(ans > 0) return ans;
ans = 1;
for(int j = i-1; j >= 0; j--)
if(G[i][j]) ans = max(ans, dp(j)+1);
return ans;
}
void _G(int len){ //存图
for(int i = 0; i < len-1; i++)//从1开始 第0个的G[0]就应该是0
{
for(int j = i+1; j < len; j++) {
if(a[j]>a[i]) G[j][i] = 1;
}
}
}
void init(){
memset(a, 0, sizeof(a));
memset(G, 0, sizeof(G));
memset(d, 0, sizeof(d));
}
int main(){
int N;
cin >> N;
while(N--){
init();
scanf("%s", a);
int len = strlen(a);
_G(len); // 存好图
int ans = 0; // ans是答案
for(int i = 0; i < len; i++){
ans = max(ans, dp(i));
}
printf("%d\n", ans);
}
return 0;
}//这个代码中的存图会导致内存爆炸 , 过不了 !!! 还有这个即便内存不爆, 估计也会超时。
//接下来换了一种时间复杂度O(nlgn)的算法求最大上升子序列:(成功AC)
<pre name="code" class="cpp">#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstdlib>
using namespace std;
const int MAXN = 10000+5;
char lismin[MAXN], str[MAXN];
int lower_bound(char* A, int x, int y, int v, char* B){
int m;
while(x<y){
m = x+(y-x)/2;
if(A[m]>=B[v]) y = m;
else x = m+1;
}
return x;
}
int main(){
int T;
cin >> T;
while(T--){
memset(str, '\0', sizeof(str));
cin >> str;
int l = strlen(str);
int len = 1;
lismin[1] = str[0];
for(int i = 1; i < l; i++){
if(str[i]>lismin[len]) lismin[++len] = str[i];
else {
int pos = lower_bound(lismin, 0, len, i, str);
lismin[pos] = str[i];
}
}
cout << len << endl;
}
return 0;
}