LA3942 Remember the Word(Trie+DP)
來源:程序員人生 發布時間:2014-10-11 08:00:01 閱讀次數:2886次
Trie圖的簡單應用。這題關鍵是想出遞推式。令d(i)表示從字符i開始的字符串,d(i)=sum{d(i+len(x))},x是s[i...L]的前綴。然后把所有可分解成的單詞構造成一顆Trie樹,再讓母串在上面跑,d[0]即是方案總數。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define mod 20071027
#define M 400005
using namespace std;
int n,top,len;
int tree[M][27];
char S[M];
char p[105];
int val[M];
int d[M];
void init()
{
top=1;
memset(tree,0,sizeof(tree));
memset(d,0,sizeof(d));
}
int idx(char c)
{
return c-'a';
}
void insert(char *s)
{
int Len=strlen(s);
int u=0;
for(int i=0;i<Len;i++)
{
int c=idx(s[i]);
if(!tree[u][c])
{
val[top]=0;
tree[u][c]=top++;
}
u=tree[u][c];
}
val[u]=1;
}
int query(char *s,int start)
{
int count=0;
int u=0;
for(int i=start;i<len;i++)
{
int c=idx(s[i]);
u=tree[u][c];
if(!u) return count;
if(val[u])
{
count+=d[i+1];
count%=mod;
}
}
return count;
}
int main()
{
int t=1;
//freopen("d: est.txt","r",stdin);
while(scanf("%s",S)!=EOF)
{
scanf("%d",&n);
init();
for(int i=0;i<n;i++)
{
scanf("%s",p);
insert(p);
}
len=strlen(S);
d[len]=1;
for(int i=1;i<=len;i++)
{
d[len-i]=query(S,len-i);
}
cout<<"Case "<<t++<<": "<<d[0]<<endl;
}
return 0;
}
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈