单调递增最长子序列
时间限制:
3000 ms | 内存限制:
65535 KB
难度:
4
-
描述
-
求一个字符串的最长递增子序列的长度
如:dabdbf最长递增子序列就是abdf,长度为4-
输入
-
第一行一个整数0<n<20,表示有n个字符串要处理
随后的n行,每行有一个字符串,该字符串的长度不会超过10000
输出
输出字符串的最长递增子序列的长度
AC 代码一:(二分思想)
#include<stdio.h> #include<stdlib.h> #include<string.h> int q(char stack[],int b,int e,char elem) { if(b>=e) return e; int mid=(b+e)/2; if(elem>stack[mid]) return q(stack,mid+1,e,elem); else return q(stack,b,mid,elem); } int main() { char stack[10005]; int n; scanf("%d",&n); while(n--) { char str[10005]; scanf("%s",str); int top=0; stack[top++]=str[0]; int i; for(i=1;i<strlen(str);i++) if(str[i]>stack[top-1]) stack[top++]=str[i]; else stack[q(stack,0,top-1,str[i])]=str[i]; printf("%d\n",top); } return 0; }
AC代码二:
#include<iostream> #include<string> using namespace std; int main() { int n; cin>>n; while(n--) { string str; cin>>str; int count=1; int a[200]; a[0]=-100; int i,j; for(i=0;i<str.size();i++) for(j=count-1;j>=0;j--) if((int)str[i]>a[j])//在a数组中找到第一个比他小的 { a[j+1]=str[i]; if(j==count-1) count++; break; } cout<<count-1<<endl;//count在判断之前的初值为1,多级算了一个。 } return 0; }
AC代码三:DP求解
#include<iostream> #include<string> #include<cstdio> #include<cstring> #define N 10010 using namespace std; int dp[N]; char s[N]; int main() { int len,test,i,j,max; scanf("%d",&test); while(test--) { scanf("%s",&s); len=strlen(s); dp[0]=1; for(i=1;i<len;i++) { max=0; for(j=i-1;j>=0;j--) { if(s[i]>s[j]&&max<dp[j]) { max=dp[j]; } } dp[i]=max+1;//dp[i]代表以i结尾也包括i在内的递增子序列的长度 } max=dp[0]; for(i=1;i<len;i++) if(max<dp[i]) max=dp[i]; printf("%d\n",max); } return 0; }
-
第一行一个整数0<n<20,表示有n个字符串要处理