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 }

 

你可能感兴趣的:(word)