zoukankan      html  css  js  c++  java
  • codevs1040:统计单词个数

    题目描述 Description

    给出一个长度不超过200的由小写英文字母组成的字母串(约定;该字串以每行20个字母的方式输入,且保证每行一定为20个)。要求将此字母串分成k份(1<k<=40),且每份中包含的单词个数加起来总数最大(每份中包含的单词可以部分重叠。当选用一个单词之后,其第一个字母不能再用。例如字符串this中可包含this和is,选用this之后就不能包含th)(管理员注:这里的不能再用指的是位置,不是字母本身。比如thisis可以算做包含2个is)。


    单词在给出的一个不超过6个单词的字典中。
    要求输出最大的个数。
    输入描述 Input Description

    第一行为一个正整数(0<n<=5)表示有n组测试数据
    每组的第一行有二个正整数(p,k)
    p表示字串的行数;
    k表示分为k个部分。
    接下来的p行,每行均有20个字符。
    再接下来有一个正整数s,表示字典中单词个数。(1<=s<=6)
    接下来的s行,每行均有一个单词。

    输出描述 Output Description

    每行一个整数,分别对应每组测试数据的相应结果。

     

    样例输入 Sample Input

    1
    1 3
    thisisabookyouareaoh
    4
    is
    a
    ok
    sab

    样例输出 Sample Output

    7

    数据范围及提示 Data Size & Hint

    this/isabookyoua/reaoh

    题解

    AC自动机+划分dp。。。有点长,不过思路挺明确。

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<string>
      5 #define maxn 150
      6 using namespace std;
      7 int tot,trie[maxn][30],fail[maxn],flg[maxn],q[maxn],wl[maxn];
      8 char str[30];
      9 string z;
     10 int n,k,m;
     11 int vis[205];
     12 int f[205][45],a[205][205];
     13 void insert(char *s)
     14 {
     15     int cnt(0);
     16     int len = strlen(s);
     17     int p = 0;
     18     for(int i = 0 ; i < len; i ++)
     19     {
     20         int id = s[i] -'a';
     21         if(!trie[p][id]) p = trie[p][id] = ++tot;
     22         else p = trie[p][id];
     23         ++cnt;
     24     }
     25     flg[p] = 1;
     26     wl[p]=cnt;
     27 }
     28 
     29 void getfail()
     30 {
     31     int p = 0,Head = 0,Tail = 0;
     32     q[++Tail] = p;
     33     while(Head != Tail)
     34     {
     35         p = q[++Head];
     36         for(int i = 0 ; i < 26; i ++)
     37         {
     38             int x = trie[p][i];
     39             if(x)
     40             {
     41                 fail[x] = p ? trie[fail[p]][i] :0;
     42                 q[++Tail] = x;
     43             }
     44             else trie[p][i] = trie[fail[p]][i];      
     45         }
     46     }
     47 }
     48 
     49 int match(int len)
     50 {
     51     int cnt(0);
     52     int p = 0;
     53     for(int i = 0 ; i <= len ; i ++)
     54     {
     55         int id = z[i] - 'a';
     56         p = trie[p][id];
     57         int t = p;
     58         while(t)
     59         {
     60             if(flg[t]&&!vis[i-wl[t]+1])
     61             {
     62                 cnt++;
     63                 vis[i-wl[t]+1]=1;
     64             } 
     65             t = fail[t];
     66         }    
     67     }
     68     return cnt;
     69 }
     70 void init()
     71 {
     72     scanf("%d%d",&n,&k);
     73     --k;
     74     for(int i=1 ; i<=n ; ++i)
     75         {
     76             scanf("%s",str);
     77             z+=str;
     78         }
     79     n=20*n-1;
     80     scanf("%d",&m);
     81     for(int i=1; i<=m ;++i)
     82     {
     83         scanf("%s",str);
     84         insert(str);
     85     }
     86     getfail();
     87     for(int i=0 ;i<=n ; ++i)
     88     {
     89         for(int j=0;j<=i;++j)vis[j]=0;
     90         f[i][0]=match(i);
     91         a[0][i]=f[i][0];
     92         if(a[0][i])
     93             for(int j=1; j<=i ; ++j)
     94             {
     95                 a[j][i]=a[j-1][i]-vis[j-1];
     96                 if(!a[j][i])break;
     97             }        
     98     }
     99 }
    100 void dp()
    101 {
    102     for(int p=1;p<=k;++p)
    103         for(int i=p;i<=n;++i)
    104             for(int j=p-1;j<i;++j)
    105                 f[i][p]=max(f[i][p],f[j][p-1]+a[j+1][i]);
    106     printf("%d
    ",f[n][k]);        
    107 }
    108 void sta()
    109 {
    110     for(int i=0 ; i<=n ;++i)
    111     {
    112         for(int j=0 ; j<45 ; ++j)
    113             f[i][j]=0;
    114         for(int j=0 ; j<=n ; ++j)
    115             a[i][j]=0;
    116     }
    117     for(int i=0; i<150 ; ++i)
    118     {
    119         fail[i]=flg[i]=wl[i]=q[i]=0;
    120         for(int j=0;j<30;++j)
    121             trie[i][j]=0;
    122     }
    123     tot=0;
    124     z="";
    125 }
    126 int main(){
    127     int T;
    128     scanf("%d",&T);
    129     while(T--)
    130     {
    131         init();
    132         dp();
    133         sta();
    134     }
    135     return 0;
    136 }
  • 相关阅读:
    cookie和session及token的区别联系
    linux/Deepin /Debian 9 Stretch安装Wine
    Deepin 15.9系统直接运行exe运行程序
    cookie和session及token的区别联系
    Deepin 15.9系统直接运行exe运行程序
    deepin系统右键刷新解决增删改文件没有变化
    linux/Deepin /Debian 9 Stretch安装Wine
    deepin系统右键刷新解决增删改文件没有变化
    Linux系统中的截图功能(类似QQ、微信、Snipaste截图功能)
    Linux系统中的截图功能(类似QQ、微信、Snipaste截图功能)
  • 原文地址:https://www.cnblogs.com/fujudge/p/7545963.html
Copyright © 2011-2022 走看看