这题dp思想很简单,主要用到了字典树记录单词是否出现,即字典的功能。不过刚开始做数据结构的题,还没有联想到和dp结合。这是一次思维的突破吧。
还有就是计算字典树节点的个数,得用字符串的长度*个数得来。
代码:
#include<iostream>
#include<cstdio>
#include<vector>
#include<string>
#include<queue>
#include<cmath>
#include<algorithm>
#include<cstring>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define maxn 300005
#define maxm 105
#define INF 0xfffffff
#define mem(a,b) memset(a,b,sizeof(a))
#define FOR(i,s,t) for(int i=s;i<=t;i++)
#define ull unsigned long long
#define ll long long
#define MOD 20071027
using namespace std;
char s[maxn],S[4005][105];
int dp[maxn];
struct trie
{
int ch[26];
int val;
trie(){memset(ch,0,sizeof(ch));val=0;}
}T[400005];
int num=0;
void build(char *s)
{
int l=strlen(s);
int p=0;
for(int i=0;i<l;i++)
{
int c=s[i]-'a';
if(T[p].ch[c]==0)
{
T[p].ch[c]=++num;
}
p=T[p].ch[c];
}
T[p].val=1;
}
bool search(char *s,int l)
{
int p=0;
for(int i=0;i<l;i++)
{
int c=s[i]-'a';
if(T[p].ch[c]==0)
{
return false;
}
p=T[p].ch[c];
}
if(T[p].val==1)
return true;
else
return false;
}
void init(int n)
{
num=0;
memset(dp,0,sizeof(dp));
for(int i=0;i<400005;i++)
{
T[i].val=0;
memset(T[i].ch,0,sizeof(T[i]));
}
}
int main()
{
int tt=1;
while(scanf("%s",s)!=EOF)
{
int n;
scanf("%d",&n);init(n);
for(int i=0;i<n;i++)
{
scanf("%s",S[i]);
build(S[i]);
}
int l=strlen(s);
dp[l]=1;
for(int i=l-1;i>=0;i--)
{
for(int j=1;j<=100;j++)
{
if(i+j>l) break;
if(search(s+i,j))
{
dp[i]=(dp[i]+dp[i+j])%MOD;
}
}
}
printf("Case %d: %d\n",tt++,dp[0]);
}
return 0;
}