描述
求一个字符串的最长递增子序列的长度
如:dabdbf最长递增子序列就是abdf,长度为4
AC代码:
如:dabdbf最长递增子序列就是abdf,长度为4
-
输入
- 第一行一个整数0<n<20,表示有n个字符串要处理
随后的n行,每行有一个字符串,该字符串的长度不会超过10000
输出 - 输出字符串的最长递增子序列的长度 样例输入
-
3 aaa ababc abklmncdefg
样例输出 -
1 3 7
思路:设dp[i]是前i个字符组成的最长递增子序列的长度。dp[1]=1; 试想,求第i个字符的最长递增子序列的长度时,扫描前i-1个字符j,如果s[i]>s[j]那么s[i]可以添加到dp[j]后面,这时dp[i] = dp[j]+1,那么我们想得到最大的dp[i],就需要得到最大的dp[j]加上1就是dp[i]。
其中容易犯的错误是1.扫描前i-1个字符的时候,判断语句容易写错。2.寻找最大上升递增子序列的时候直接返回以最后一个字符结束的最大上升递增子序列。
void LIS(String s){
for(int i=1 ;i<s.length() ;i++){
dp[i] = 1;
for(int j=0 ;j<i ;j++){
if(s[j]<s[i]){
//错误1 dp[i] = max(dp[j]+1,1);
dp[i] = max(dp[j]+1,dp[i]);
}
}
ans = max(ans,dp[i]);
}
//错误2 ans = dp[s.length()-1];
}
AC代码:
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
string s;
int n,dp[10005],ans;
int main(){
scanf("%d",&n);
while(n--){
cin>>s;
dp[0] = 1;
ans = 1;
for(int i=1 ;i<s.length() ;i++){
dp[i] = 1;
for(int j=0 ;j<i ;j++){
if(s[j]<s[i]){
dp[i] = max(dp[j]+1,dp[i]);
}
}
ans = max(ans,dp[i]);
}
printf("%d\n",ans);
}
return 0;
}