NYOJ 17(LIS)

 

单调递增最长子序列

时间限制:3000 ms  |  内存限制:65535 KB 

难度:4

描述 

求一个字符串的最长递增子序列的长度

如:dabdbf最长递增子序列就是abdf,长度为4 

输入 

第一行一个整数0<n<20,表示有n个字符串要处理

随后的n行,每行有一个字符串,该字符串的长度不会超过10000 

输出 

输出字符串的最长递增子序列的长度 

样例输入 

3

aaa

ababc

abklmncdefg样例输出 

1

3

7

 

 在求以ai为末元素的最长递增子序列时,找到所有序号在L前面且小于ai的元素aj,即j<i且aj<ai。如果这样的元素存在,那么对所有aj,都有一个以aj为末元素的最长递增子序列的长度f(j),把其中最大的f(j)选出来,那么f(i)就等于最大的f(j)加上1,即以ai为末元素的最长递增子序列,等于以使f(j)最大的那个aj为末元素的递增子序列最末再加上ai;如果这样的元素不存在,那么ai自身构成一个长度为1的以ai为末元素的递增子序列。

 

 

//AC

 

#include<stdio.h>

#include<string.h>

#define N 10001

int dp(char str[],int n)

{

int i,j;int max;int d[N];

for(i=0;i<N;i++)

d[i]=1;

for(i=n-2;i>=0;i--)

for(j=i+1;j<=n-1;j++)

if(str[j]>str[i]&&d[i]<d[j]+1)

d[i]=d[j]+1;//不能是d[i]++,因为要保证递增

max=d[0];

for(i=1;i<n;i++)

{

if(max<d[i])

max=d[i];

}

return max;

}

int main()

{

int i,j,len;int T,ans;

char str[N];

scanf("%d",&T);

for(i=1;i<=T;i++)

{

scanf("%s",str);

//memset(str,0,sizeof(str));

len=strlen(str);

ans=dp(str,len);

printf("%d\n",ans);

}

return 0;

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

//wa,必须把d[N]开在函数内并初始化为1,

#include<stdio.h>

#include<string.h>

#define N 10001

int d[N];

char str[N];

int dp(char str[],int n)

{

int i,j;int max;

for(i=n-2;i>=0;i--)

for(j=i+1;j<=n-1;j++)

if(str[j]>str[i]&&d[i]<d[j]+1)

d[i]=d[j]+1;//不能是d[i]++,因为要保证递增

max=d[0];

for(i=1;i<n;i++)

{

if(max<d[i])

max=d[i];

}

return max;

}

int main()

{

int i,j,len;int T,ans;

scanf("%d",&T);

for(i=0;i<N;i++)

d[i]=1;

for(i=1;i<=T;i++)

{

scanf("%s",str);

//memset(str,0,sizeof(str));

len=strlen(str);

ans=dp(str,len);

printf("%d\n",ans);

}

return 0;

}

 

 

 
原文地址:https://www.cnblogs.com/hxsyl/p/2464694.html