1 条题解

  • 0
    @ 2025-8-24 21:25:35

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar Rainbow_qwq
    **

    搬运于2025-08-24 21:25:34,当前版本为作者最后更新于2019-02-01 09:58:16,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    原题链接

    字符串版最长上升子序列。

    各位大佬都用string吗?

    虽然string方便,但我不会用string,所以我还是用char数组好了。。

    看到一个大佬用char的函数strncmp(),其实,char里也有一个函数,叫做:

    strstr(s1,s2)
    
    作用:
    判断s2是否为s1的子串。
    如果没找到,返回NULL;
    如果找到了,返回这个子串第一个字符的地址。
    
    如:
    char s1[]="habch",s2[]="abc"
    strstr(s1,s2)就返回s1中'a'的地址
    
    头文件为:
    
    #include<cstring>
    

    估计没什么人知道吧。。。

    于是我果断打了一个dp代码:

    #include<bits/stdc++.h>
    using namespace std;
    char s[2010][80];//二维char存储多个字符串
    int f[2010],n,ans;
    int main()
    {
    	ios::sync_with_stdio(0);//cin,cout优化
    	cin>>n;
    	for(int i=1;i<=n;i++)
    	{
    		cin>>s[i];//整行读入
    		f[i]=1;
    		for(int j=i-1;j>=1;j--)
    			if(strstr(s[i],s[j])!=NULL)//找得到这个子串
    				f[i]=max(f[j]+1,f[i]);//dp处理
    		ans=max(f[i],ans);
    	}
    	cout<<ans;
    	return 0;
    }
    

    但是交上去,WA了一半。。。

    后来,我发现了问题:

    s1="hhhabchhh"
    s2="abc"
    s2是s1的子串,但s2并不能接在s1上,不能组成词链。
    要想要s2能接在s1上,则s2首字符地址==s1首字符地址
    所以我们修改代码:
    
    for(int j=i-1;j>=1;j--)
    	if(strstr(s[i],s[j])==s[i])
        //不仅要找得到这个子串,还必须能接在s[i]上
        //即:返回的首字符地址==s[i]的首字符地址
    		f[i]=max(f[j]+1,f[i]);//符合要求,进行dp
    ans=max(f[i],ans);
    

    修改后终于AC了!

    AC 代码:

    #include<bits/stdc++.h>
    using namespace std;
    char s[2010][80];
    int f[2010],n,ans;
    int main()
    {
    	ios::sync_with_stdio(0);
    	cin>>n;
    	for(int i=1;i<=n;i++)
    	{
    		cin>>s[i];
    		f[i]=1;
    		for(int j=i-1;j>=1;j--)
    			if(strstr(s[i],s[j])==s[i])
    				f[i]=max(f[j]+1,f[i]);
    		ans=max(f[i],ans);
    	}
    	cout<<ans;
    	return 0;
    }
    
    • 1

    信息

    ID
    474
    时间
    1000ms
    内存
    125MiB
    难度
    3
    标签
    递交数
    0
    已通过
    0
    上传者