zoukankan      html  css  js  c++  java
  • 最长前缀 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;
    }
    
    

    总结

    时间复杂度能减则减

  • 相关阅读:
    "less is more",用"less”命令查看linux文本文件
    Linux命令"ls"进阶说明
    Linux文件权限说明
    Ubuntu14.04安装Ruby2.2方法
    Ubuntu查找软件命令
    Using If/Truth Statements with pandas
    Categorical Data
    DataFrame.loc的区间
    pandas学习(一)
    JDBC编程之事务处理
  • 原文地址:https://www.cnblogs.com/resftlmuttmotw/p/11323328.html
Copyright © 2011-2022 走看看