- 【描述】
-
求一個字符串的最長遞增子序列的長度
如:dabdbf最長遞增子序列就是abdf,長度為4
- 【輸入】
-
第一行一個整數0<n<20,表示有n個字符串要處理
隨后的n行,每行有一個字符串,該字符串的長度不會超過10000 - 【輸出】
- 輸出字符串的最長遞增子序列的長度
方法一:
=================================
=========
用一個數組保存以當前字符作為結束的最長字串
對于一個字符串 s ,申請同樣長度的數組 X,X[i] 表示以s[i]結束的最長單調遞增子串
X[i] = max{ X[j]+1 } ,其中0≤j<i,且s[j]<s[i]
則s的最長升序子串為 max{ X[i] }
復雜度O(N^2)
#include<iostream>
#include<string>
using namespace std;
int main(){
int N;
cin >> N;
string s;
while(N--){
cin >> s;
int* x = new int[s.length()];
for (unsigned int i=0;i<s.length();i++)
x[i] = 1;
int max = 1;
for(unsigned int i=1;i<s.length();i++){
for(int j=i-1;j>=0;j--) {
if(s[j]<s[i]){
if(x[j]+1>x[i]){
x[i] = x[j]+1;
}
}
}
if(max<x[i]) max = x[i];
}
cout << max << endl;
}
return 0;
}
方法二:
?
==========================================
用一數組保存最長長度為下標的最小字符。
#include<iostream>
#include <string>
using namespace std;
int main()
{
int n ;
cin>>n;
while(n--){
string str;
int count=1;
cin>>str;
int a[200];
a[0]=-999;
for (int i=0;i<str.length();i++){
for (int j=count-1;j>=0;j--){
if((int)str[i]>a[j]){
a[j+1]=str[i];
if(j+1==count) count++;
break;
}
}
}
cout<<count-1<<endl;
}
return 0;
}
?
方法三:
=======================================================
?如果字符的范圍有限,那么可以有O(N)時間的算法。
設串的字符集為S,包含N個元素,每個元素為Ak,Ai < Aj (0 <= i < j < N)。
設串T中以Ap結尾的單調遞增子序列長度為len(T, Ap),則T的單調遞增子序列長度為Maxlen(T) = max(len(T,A0), len(T, A1), ..., len(T,An-1))。
如果給串T的末尾再添加一個字符Aq,則len(T + Aq, Aq) = len(T, Aq - 1) + 1。?
#include<stdio.h>
int length(char * s)
{
int len[128] = {0}, i, t;
for(; *s != '\0' ; s++){
t = len[*s - 1] + 1;
for(i = *s; i < 128 && len[i] < t; i++)
len[i] = t;
}
return len[127];
}
int main()
{
int n;
char s[10001];
for(scanf("%d\n", &n); n--;)
printf("%d\n", length(gets(s)));
return 0;
}
?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

