zoukankan      html  css  js  c++  java
  • USACO2.3.1 The Longest Prefix 题解

    【算法】动态规划  【难度】★★☆☆☆


    这道题花费了很长时间(话说好像没有那道题时间短的)其实很显然是DP,状态转移方程也很容易想到(我是参考了最长公共子序列的思想)。设f[i]表示第i个是否在前缀中,则:

    {dp[i]=max{dp[j]+j-i}|i到j-1的字串是primitive。 i<j<=n}

    如果没有i-j<=10最坏情况下就会超时!我在这纠结了半天,参照别人的题解才想到的。
    还有一点是关于元素的判断。最初是用strcmp但是也会超时。想到了hash,搜了一下有题解说可以把每个元素变成10位2进制数,但是我没找到到底怎么做(= =)。。。所以还是说一下我的方法,也是hash:因为英文字母只有26个,所以2进制下最多5位,最长10个字母也就是50位,还是可以存下的。因为最多只有200个元素,用的时候搜一下就可以了。

    【收获】状态转移方程的边界条件很重要

    View Code
     1 /*
    2 ID: wsc5001
    3 LANG: C
    4 TASK: prefix
    5 */
    6 #include <stdio.h>
    7 #include <stdlib.h>
    8 #include <string.h>
    9 char list[203][12];
    10 int lenlist[12][203];
    11 long long hash[202];
    12 char s[200002];
    13 int cs;
    14 int ct;
    15 int f[200010];
    16 int pd(int b,int e)
    17 {
    18 int i,j,k;
    19 long long bf=0;
    20 for (i=b;i<=e;i++)
    21 {
    22 if (s[i]>='A'&&s[i]<='Z') bf+=s[i]-'A'+1;
    23 bf=(bf<<5);
    24 }
    25 for (i=0;i<10+1-e+b-1;i++)
    26 bf=(bf<<5);
    27 for (i=0;i<ct;i++)
    28 if (hash[i]==bf)
    29 return 1;
    30 return 0;
    31 }
    32 long long hashit(int coin)
    33 {
    34 int i,j,k;
    35 long long ans=0;
    36 for (i=0;i<10+1;i++)
    37 {
    38 if (list[coin][i]>='A'&&list[coin][i]<='Z') ans+=list[coin][i]-'A'+1;
    39 ans=(ans<<5);
    40 }
    41 return ans;
    42 }
    43 int main()
    44 {
    45 freopen("prefix.in","r",stdin);
    46 freopen("prefix.out","w",stdout);
    47 int i,j,k,flag,e;
    48 char gabbage;
    49 for (i=0;i<12;i++)
    50 lenlist[i][0]=1;
    51 i=0;
    52 scanf("%s",&list[i]);
    53 while (list[i][0]!='.')
    54 {
    55 hash[i]=hashit(i);
    56 i++;
    57 scanf("%s",&list[i]);
    58 }
    59 ct=i;
    60 i=0;flag=0;
    61 scanf("%c",&gabbage);
    62 while (1)
    63 {
    64 scanf("%c",&gabbage);
    65 if (gabbage>='A'&&gabbage<='Z')
    66 {s[i]=gabbage;i++;flag=0;}
    67 else
    68 flag+=1;
    69 if (flag==2)
    70 break;
    71 }
    72 cs=i;
    73 f[0]=1;
    74 for (i=1;i<=cs;i++)
    75 {
    76 for (j=i-1;j>=0;j--)
    77 {
    78 if (i-j+1>12||f[i]==1) break;//important!!!!!!
    79 e=pd(j,i-1);
    80 if (e==1&&f[j]==1)
    81 {f[i]=1;}
    82 }
    83 }
    84 //printf("%d\n",cs);
    85 //for (i=1;i<=cs;i++) printf("%d ",f[i]); printf("\n");
    86 flag=0;
    87 for (i=cs;i>=1;i--)
    88 if (f[i]==1)
    89 {printf("%d\n",i);flag=1;break;}
    90 if (flag==0) printf("0\n");
    91 //system("pause");
    92 fclose(stdin);
    93 fclose(stdout);
    94 }



  • 相关阅读:
    jQuery中ajax的4种常用请求方式
    前端常见浏览器兼容性问题解决方案
    平衡二叉树---将有序数组转换为二叉搜索树
    equals
    Java中的System.out.println
    System.arraycopy --全面解释(就是那么有爱心)
    计算机网络实验-ACL-OSPF-RIP
    pip install lxml
    Spark-shell --常用命令 (command)
    《Thinking in Java》---Summary of Chapter 2
  • 原文地址:https://www.cnblogs.com/loveidea/p/2416938.html
Copyright © 2011-2022 走看看