Remember the Word

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

题意:给以一个串,然后给你一些单词,问你这个串由这些单词组成的话,可以有多少种组成方式。

题解:这是白书上的一道题目。开始,觉得是DP,但是不知道怎么搞。看了白书上的解释,慢慢的才弄了出来。用dp【i】表示从i到strlen(s)-1最多的组成方式,即以字符i开头。这样的话,就很明显了,dp【i】=sum(dp[i+len(x)])(x是i.....len-1的前缀),那么只要查询i....len-1之间的前缀,如果找到一个前缀,就更新。通过这一题,有了更深的体会,Trie树的另外一个名字,前缀树。

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<algorithm>
 5 #define maxn 1100000
 6 using namespace std;
 7 int dp[300002];
 8 char str[300002];
 9 int current;
10 struct Nod {        //0为无效值
11     int lnk[26], val;
12     char ss[28];
13     void init() {
14         memset(lnk, 0, sizeof(lnk));
15         memset(ss, 0, sizeof(ss));
16         val = 0;
17     }
18 };
19 const char BASE = 'a';
20 struct Trie {
21     Nod buf[maxn];
22     int len;
23     void init() {
24         buf[len=0].init();
25     }
26     void insert(char * str) {
27         int now = 0;
28         for(int i = 0; str[i]; i ++) {
29             int & nxt = buf[now].lnk[str[i]-BASE];
30             if(!nxt)buf[nxt=++len].init();
31              now = nxt;
32         }
33          buf[now].val=1;
34     }
35     void  search(char * str) {
36         int now = 0;
37         for(int i = 0; str[i]; i ++) {
38             int & nxt = buf[now].lnk[str[i]-BASE];
39             now = nxt;
40             if(!nxt)return;//注意这里的返回,不然会tle
41             if(buf[now].val==1){
42                 dp[current]=(dp[current]+dp[current+i+1])%20071027;
43             }
44         }
45     }
46 } trie;
47 int n;
48 char ss[103];
49 char s1[300002];
50  int main(){
51      int tt=1;
52      while(~scanf("%s",str)){
53      trie.init();
54      scanf("%d",&n);
55      memset(dp,0,sizeof(dp));
56      while(n--){
57         scanf("%s",ss);
58         trie.insert(ss);
59      }
60       int len=strlen(str);
61           dp[len]=1;
62       for(int i=len-1;i>=0;i--){
63            current=i;
64           trie.search(str+i);
65       }
66       printf("Case %d: %d\n",tt++,dp[0]);
67   }
68 }
View Code

 

posted on 2014-07-15 10:30  天依蓝  阅读(286)  评论(0编辑  收藏  举报

导航