LA 3942 Remember the Word(Trie树 + dp)

https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1943

题意:给出一个由S个不同单词组成的字典和一个长字符串。把这个字符串分解成若干个单词的连接(单词可重复使用),有多少种方法?

解题思路:用Trie存入字典,设dp[i]为从字符i开始的字符串的分解方案数,

则有dp[i] = sum{dp[i+len(x)] | 单词x为S[i...L]的前缀}。

139MS
 1 /*
 2  *Author:       Zhaofa Fang
 3  *Created time: 2013-04-02-21.55
 4  *Language:     C++
 5  */
 6 #include <cstdio>
 7 #include <cstdlib>
 8 #include <sstream>
 9 #include <iostream>
10 #include <cmath>
11 #include <cstring>
12 #include <algorithm>
13 #include <string>
14 #include <utility>
15 #include <vector>
16 #include <queue>
17 #include <stack>
18 #include <map>
19 #include <set>
20 using namespace std;
21 
22 typedef long long ll;
23 #define DEBUG(x) cout<< #x << ':' << x << endl
24 #define REP(i,n) for(int i=0;i < (n);i++)
25 #define REPD(i,n) for(int i=(n-1);i >= 0;i--)
26 #define FOR(i,s,t) for(int i = (s);i <= (t);i++)
27 #define FORD(i,s,t) for(int i = (s);i >= (t);i--)
28 #define PII pair<int,int>
29 #define PB push_back
30 #define MP make_pair
31 #define ft first
32 #define sd second
33 #define lowbit(x) (x&(-x))
34 #define INF (1<<30)
35 
36 const int maxnode = 400111;
37 const int sigma_size = 26;
38 const int mod = 20071027;
39 int dp[300111];
40 char str[300111];
41 int ch[maxnode][sigma_size];
42 struct Trie{
43 
44     bool val[maxnode];
45     int sz;
46     Trie(){sz = 1;memset(ch[0],0,sizeof(ch[0]));}
47     int idx(char c){return c-'a';}
48 
49     void insert(char *S){
50         int u = 0, len = strlen(S);
51         REP(i,len){
52             int c = idx(S[i]);
53             if(!ch[u][c]){
54                 memset(ch[sz],0,sizeof(ch[sz]));
55                 val[sz] = 0;
56                 ch[u][c] = sz++;
57             }
58             u = ch[u][c];
59         }
60         val[u] = 1;
61     }
62 
63     int find(char *S,int pos){
64         int ans = 0;
65         int u = 0,len = strlen(S);
66         for(int i=pos;i<len&&i<pos+101;i++){
67             int c = idx(S[i]);
68             if(!ch[u][c])return ans;
69             u = ch[u][c];
70             if(val[u])ans = (ans+dp[i+1])%mod;
71         }
72         return ans;
73     }
74 };
75 int main(){
76     //freopen("in","r",stdin);
77     //freopen("out","w",stdout);
78     int cas = 0;
79     while(~scanf("%s",str)){
80         int n;
81         scanf("%d",&n);
82         char str1[110];
83         Trie pp;
84         REP(i,n){
85             scanf("%s",str1);
86             pp.insert(str1);
87         }
88         int len = strlen(str);
89         dp[len] = 1;
90         REPD(i,len)dp[i] = pp.find(str,i);
91         printf("Case %d: %d\n",++cas,dp[0]);
92     }
93     return 0;
94 }

 

posted @ 2013-04-03 13:15  發_  阅读(545)  评论(0编辑  收藏  举报