• 最长前缀 Longest Prefix


    最易懂的题解

    题目描述

    题目描述


    做题时的垂死挣扎

    最先看到这道题,非常开心。哈哈一笑,暴力,然后快乐TLE

    请大家以我为戒,做题前先看标签。

    然后在看到DP后,我傻眼了。(我打的就是dp啊,怎么会错一个点)

    我盯着电脑,看着题,想了50多分钟无关的事后。。。我终于开始了打代码


    思路

    读入时需要注意一下字符串的技巧。

    然后你就暴力循环dp

    我最开始TLE一个点是因为,我顺便把连成长度为 K 的前缀的方法总数也顺便求了一下

    具体方法

    每向后移一个字母,就循环一下元素,看看当前元素是否与这序列 从当前位置向前遍

    历所的串相等

    for(k = i;k > i - a[j].k[11];k--)
    {
        it--;
        if(a2[k] != a[j].k[it])
    	{
            able = 1;
        	break;
        }
    }
    

    dp[k - 元素.size()] == 1
    

    才将

    
    dp[k] = 1;
    

    最后再在一些地方适当优化就可以AC了

    我的方法


    #include <cstdio>
    #include <string>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define M 200002
    #define N 202
    #define max(a,b) a >= b? a:b//手写max
    using namespace std;
    int ans,len1,i,j,len2 = 1;
    char a2[M];
    bool dp[M];
    struct node
    {
    	char k[12];
    }a[N];//主要是定义成结构体,看着好看一些,可以定成二维
    
    int main()
    {
        scanf("%s",a[len2].k);
        a[len2].k[11] = strlen(a[len2].k);//最大长度10,11存长度
        while(a[len2].k[0] != '.')//不能写成a[len2].k !=  "."
    	{
            len2++;
            scanf("%s",a[len2].k);
            a[len2].k[11] = strlen(a[len2].k);
        }
        len2--;
        char x = getchar();//去掉'.'后的换行符
        
        while(~scanf("%c",&x))
            if(x <= 'Z'&&x >= 'A')
    		{
                len1++;
                a2[len1] = x;
            }
        //至此,读入环节结束
        dp[0] = 1;
        for(i = 1;i <= len1;i++)
    	{
            int k;
            for(j = 1;j <= len2;j++)
    		{
                if(i < a[j].k[11]) continue;//i < 长度,肯定不行的啦
                bool able = 0;
                int it = a[j].k[11];//因为下面--
                for(k = i;k > i - a[j].k[11];k--)
    			{
                    it--;
                    if(a2[k] != a[j].k[it])
    				{
                        able = 1;
                        break;
                    }
                }
                if(!able)
    			{
                    dp[i] += dp[i - a[j].k[11]];//就这里,顺便求了下连成长度为 K 的前缀的方法总数
                    
                    if(dp[i])
                    {
                    	ans = max(ans,i);
                    	break;//必须加,不然会TLE一个点
    				}
                }
            }
        }
        printf("%d",ans);
        return 0;
    }
    
    

    总结

    时间复杂度能减则减

  • 相关阅读:
    1 基本概念 进入java世界
    一文了解kudu【转载】
    jenkins git项目clean before checkout 和 wipe out repository & force clone
    jenkins 内置判断条件
    jenkins常用插件使用说明-git publisher
    常用正则表达式
    基于ldap+sentry+rbac的hive数据库权限测试
    nginx_mirror_module流量复制在项目中的应用
    jenkins上job误删除怎么恢复
    pipeline语法学习日记
  • 原文地址:https://www.cnblogs.com/resftlmuttmotw/p/11323328.html
Copyright © 2020-2023  润新知