码迷,mamicode.com
首页 > 其他好文 > 详细

P1026 统计单词个数

时间:2018-08-05 21:23:48      阅读:148      评论:0      收藏:0      [点我收藏+]

标签:ott   正整数   isis   --   html   span   class   UNC   while   

题目描述

给出一个长度不超过 200 的由小写英文字母组成的字母串(约定;该字串以每行 20 个字母的方式输入,且保证每行一定为 20 个)。要求将此字母串分成 k 份( 1<k≤401<k \le 401<k40 ),且每份中包含的单词个数加起来总数最大(每份中包含的单词可以部分重叠。当选用一个单词之后,其第一个字母不能再用。例如字符串 this中可包含 thisis ,选用 this 之后就不能包含 th )。

单词在给出的一个不超过 6 个单词的字典中。

要求输出最大的个数。

输入输出格式

输入格式:

每组的第一行有 2 个正整数( p,k )

p表示字串的行数, k 表示分为 k 个部分。

接下来的 p 行,每行均有 20 个字符。

再接下来有 1 个正整数 s ,表示字典中单词个数。( 1≤s≤61 \le s \le 61s6 )

接下来的 s 行,每行均有 1 个单词。

输出格式:

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

输入输出样例

输入样例#1: 
1 3
thisisabookyouareaoh
4
is
a
ok
sab
输出样例#1: 
7

说明

this/isabookyoua/reaoh

 

Solution:

  字符串dp,套路就是定义状态$f[i][j]$表示到了母串$i$位置分成$j$块包含的单词最大个数。

  对于本题,如果我们知道$s[i][j]$(表示母串$i$到$j$之间的单词个数),则很容易将其转化为区间dp,不难得到状态转移方程:$f[i][j]=max(f[i][j],f[p][j-1]+s[p+1][i]),\;p\in [1,i)$。

  那么本题解决关键成了如何预处理$s[i][j]$,我的方法是字符串hash+暴力枚举,对母串和各匹配串均hash一下,然后直接枚举区间和断点,判断hash值是否相等就好了,然后注意细节:1、求hash值时可能爆int  2、每个位置只能做为一个匹配串的开头,匹配到了就直接break掉。

代码:

 

 1 #include<bits/stdc++.h>
 2 #define il inline
 3 #define ll long long
 4 #define For(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
 5 #define Bor(i,a,b) for(int (i)=(b);(i)>=(a);(i)--)
 6 using namespace std;
 7 const int mod=998244353,P=131;
 8 int op[205],ha[205],l[7],p[7];
 9 int n,m,k,len,f[205][45],g[205][205];
10 char s[205],t[205];
11 bool vis[205];
12 
13 il void init(){
14     cin>>m>>k;
15     while(m--) For(i,1,20) cin>>s[++len];
16     op[0]=1;
17     For(i,1,len) op[i]=1ll*op[i-1]*P%mod,ha[i]=(1ll*ha[i-1]*P%mod+s[i]-a)%mod;
18     cin>>n;
19     For(i,1,n) {
20         cin>>t+1,l[i]=strlen(t+1);
21         For(j,1,l[i]) p[i]=(1ll*p[i]*P+t[j]-a)%mod;
22     }
23     For(i,1,len) For(j,i,len) For(k,i,j) For(o,1,n)
24         if(k+l[o]-1<=j&&(ha[k+l[o]-1]-1ll*ha[k-1]*op[l[o]]%mod+mod)%mod==p[o]){g[i][j]++;break;}
25 }
26 
27 int main(){
28     ios::sync_with_stdio(0);
29     init();
30     For(o,1,k) For(i,1,len) For(j,o-1,i-1) f[i][o]=max(f[i][o],f[j][o-1]+g[j+1][i]);
31     cout<<f[len][k];
32     return 0;
33 }

 

 

 

P1026 统计单词个数

标签:ott   正整数   isis   --   html   span   class   UNC   while   

原文地址:https://www.cnblogs.com/five20/p/9427021.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!