题目大意:首先给一个字符集合,这个集合有N个字符,然后需要一个长度为M的句子,但是据子里面不能包含的串有P个,每个串里面的字符都是有字符集和里面的字符构成的,现在想知道最多能构造多少个不重复的句子。
分析:跟以前做过的那两题差不多,不过这个不让取余….不过考虑到字符长度也不大,最多也就50,所以使用一般的dp也可以。ps.在做高高精度运算的时候输出答案竟然正着输出了….然后就一直WA….确实有些时间没有敲过高精度题目了。
代码如下:
==============================================================================================================================
#include<iostream> #include<algorithm> #include<stdio.h> #include<string.h> #include<queue> using namespace std; const int MAXN = 107; const int oo = 1e9+7; char WordList[MAXN]; int MaxSon, Matrix[MAXN][MAXN]; struct Ac_Trie { int next[MAXN][MAXN], size; int Fail[MAXN], End[MAXN], root; int newnode) { memsetnext[size], -1, sizeofnext[size])); Fail[size] = End[size] = false; return size++; } void InIt) { size = 0; root = newnode); } void Insertchar s[]) { int now = root; forint i=0; s[i]; i++) { int k = strchrWordList, s[i]) - WordList; ifnext[now][k] == -1) next[now][k] = newnode); now = next[now][k]; } End[now] = true; } void GetFail) { queue<int> Q; int now = root; Fail[root] = root; forint i=0; i<MaxSon; i++) { ifnext[now][i] == -1) next[now][i] = root; else { Fail[next[now][i]] = root; Q.pushnext[now][i]); } } whileQ.size)) { now = Q.front); Q.pop); forint i=0; i<MaxSon; i++) { ifnext[now][i] == -1) next[now][i] = next[Fail[now]][i]; else { Fail[next[now][i]] = next[Fail[now]][i]; Q.pushnext[now][i]); } } End[now] |= End[Fail[now]]; } } void GetMatrix) { memsetMatrix, false, sizeofMatrix)); forint i=0; i<size; i++) forint k=0; k<MaxSon; k++) { if!End[next[i][k]] && !End[i]) Matrix[i][next[i][k]] += 1; } } }; Ac_Trie ac; void BigNumAddint a[], int num, int b[]) { forint i=0; i<MAXN; i++) b[i] += a[i] * num; forint i=0; i<MAXN-1; i++) { b[i+1] += b[i] / 10; b[i] %= 10; } } int main) { int N, P; whilescanf"%d%d%d", &MaxSon, &N, &P) != EOF) { char s[MAXN]; ac.InIt); getchar); getsWordList); whileP--) { getss); ac.Inserts); } ac.GetFail); ac.GetMatrix); int dp[2][MAXN][MAXN] = {0}, op=0; dp[1][0][0] = 1; whileN--) { memsetdp[op], false, sizeofdp[op])); forint i=0; i<ac.size; i++) forint j=0; j<ac.size; j++) { ifMatrix[i][j]) {///dp[op][j] += dp[op^1][i] * Matrix[i][j]; BigNumAdddp[op^1][i], Matrix[i][j], dp[op][j]); } } op ^= 1; } int ans[MAXN] = {0}; forint i=0; i<ac.size; i++) BigNumAdddp[op^1][i], 1, ans); N = MAXN - 1; whileans[N] == 0 && N > 0) N--; forint i=N; i>=0; i--) printf"%d", ans[i]); printf" "); } return 0; }