NYOJ17 单调递增最长子序列(最长单调递增子序列)

题目:

单调递增最长子序列

时间限制: 3000 ms  |  内存限制: 65535 KB
难度: 4
描述
求一个字符串的最长递增子序列的长度
如:dabdbf最长递增子序列就是abdf,长度为4
输入
第一行一个整数0随后的n行,每行有一个字符串,该字符串的长度不会超过10000
输出
输出字符串的最长递增子序列的长度
样例输入
3
aaa
ababc
abklmncdefg
样例输出
1
3
7
来源
经典题目
上传者
iphxer

代码1:

#include 
#include 
#include 
#include 
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
int main()
{
    int n;
    char str[10005];//存储字符串
    int num[10005];//当前元素作为最大元素的最长递增序列
    scanf("%d",&n);
    while(n--)
    {
        mem(str,'\0');
        mem(num,0);//初始化str和num
        int sum=0;
        num[0]=1;//第一个元素的最长递增序列一定为1
        scanf("%s",str);
        int len=strlen(str);

        for(int i=1; istr[j]&&flag

把上面的代码优化一下,可以用逆推的方式这么写

代码2:

#include  
#include  
int dp[10010];  
char a[10010];  
int main()  
{  
    int t;  
    scanf("%d",&t);  
    while(t--)  
    {  
        memset(dp,0,sizeof(dp));  
        int i,la,j,maxn=-1;  
        scanf("%s",a+1);  
        la=strlen(a+1);  
        for(i=1;i<=la;i++)  
            {  
                for(j=i-1;j>=0;j--)  
                {  
                    if(a[j]maxn)  
                    maxn=dp[i];  
            }  
            printf("%d\n",maxn);  
    }  
    return 0;  
}  



关于这个问题有一篇博客写的很好:--> 最长递增子序列详解(longest increasing subsequence)

以下内容摘自上述博客
-----------------------------------------------------------------关于单调递增子序列--------------------------------------------------------------------------------

对于动态规划问题,往往存在递推解决方法,这个问题也不例外。要求长度为i的序列的Ai{a1,a2,……,ai}最长递增子序列,需要先求出序列Ai-1{a1,a2,……,ai-1}中以各元素(a1,a2,……,ai-1)作为最大元素的最长递增序列,然后把所有这些递增序列与ai比较,如果某个长度为m序列的末尾元素aj(j    35
    35,36
    35,36,39
    3
    3,15
    3,15,27
    3,6
当新加入第10个元素42时,这些序列变为
    35,42
    35,36,42
    35,36,39,42,
    3,42
    3,15,42
    3,15,27,42
    3,6,42

这其中最长的递增序列为(35,36,39,42)和(3,15,27,42),所以序列A的最长递增子序列的长度为4,同时在A中长度为4的递增子序列不止一个。

该算法的思想十分简单,如果要得出Ai序列的最长递增子序列,就需要计算出Ai-1的所有元素作为最大元素的最长递增序列,依次

递推Ai-2,Ai-3,……,将此过程倒过来,即可得到递推算法,依次推出A1,A2,……,直到推出Ai为止

2018年3月31日20:06:37重写O(N^2)

#include 
using namespace std;
int dp[10000+100];
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int maxx=0;
        string s;
        cin>>s;
        int len=s.length();
        for(int i=0; idp[i])
                {
                    dp[i]=dp[j]+1;
                }
            }
            maxx=max(maxx,dp[i]);
        }
        cout<


你可能感兴趣的:(【LCS,LIS,编辑距离】)