1.题目描述:点击打开链接
2.解题思路:本题利用Trie+dp解决。首先,令d(i)表示从字符i开始的字符串(即后缀S[i...L])的分解方案数,那么d(i)=d(i+len(x)|单词x是S[i..L]的前缀)。如果我们枚举单词,然后判断它是否为S[i...L]的前缀,时间无法承受。所以可以考虑事先把所有的单词存入Trie,然后试着在Trie中查找S[i...L]。查找时,如果找到了一个单词结点,就把它的序号记下来,这样就找到了一个单词x,最多只需要100次比较就能找到所有的x。
3.代码:
#include<iostream> #include<algorithm> #include<cassert> #include<string> #include<sstream> #include<set> #include<bitset> #include<vector> #include<stack> #include<map> #include<queue> #include<deque> #include<cstdlib> #include<cstdio> #include<cstring> #include<cmath> #include<ctime> #include<cctype> #include<functional> #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; #define me(s) memset(s,0,sizeof(s)) #define rep(i,n) for(int i=0;i<(n);i++) typedef long long ll; typedef unsigned int uint; typedef unsigned long long ull; typedef pair <int, int> P; const int maxnode = 4000 * 100 + 10; const int sigma_size = 26; struct Trie { int ch[maxnode][sigma_size]; int val[maxnode]; int sz; void clear() { sz = 1; memset(ch[0], 0, sizeof(ch[0])); } int idx(char c) { return c - 'a'; } void insert(const char *s, int v) { int u = 0, n = strlen(s); for(int i = 0; i < n; i++) { int c = idx(s[i]); if(!ch[u][c]) { memset(ch[sz], 0, sizeof(ch[sz])); val[sz] = 0; ch[u][c] = sz++; } u = ch[u][c]; } val[u] = v; } void find_prefixes(const char *s, int len, vector<int>& ans) { int u = 0; for(int i = 0; i < len; i++) { if(s[i] == '\0') break; int c = idx(s[i]); if(!ch[u][c]) break; u = ch[u][c]; if(val[u] != 0) ans.push_back(val[u]); } } }; #include<cstdio> const int maxl = 300000 + 10; // 文本串最大长度 const int maxw = 4000 + 10; // 单词最大个数 const int maxwl = 100 + 10; // 每个单词最大长度 const int MOD = 20071027; int d[maxl], len[maxw], S; char text[maxl], word[maxwl]; Trie trie; int main() { int kase = 1; while(scanf("%s%d", text, &S) == 2) { trie.clear(); for(int i = 1; i <= S; i++) { scanf("%s", word); len[i] = strlen(word); trie.insert(word, i); } memset(d, 0, sizeof(d)); int L = strlen(text); d[L] = 1; for(int i = L-1; i >= 0; i--) { vector<int> p; trie.find_prefixes(text+i, L-i, p); for(int j = 0; j < p.size(); j++) d[i] = (d[i] + d[i+len[p[j]]]) % MOD; } printf("Case %d: %d\n", kase++, d[0]); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/u014800748/article/details/48038299