挺简单的一道题,搞了很久,主要是用java写的时候对java不熟悉,各种错误都出来了,不过学到了不少
这题用DP去构造就可以了,另有一题加强版(poj 2778)题意一样,只不过需要用到矩阵乘法
dp[i][j]表示长度为i的串走到了j节点的方案数(不包含病毒串)
先献上java代码,输入问题要注意啊,可能有大于127的字符出现,java的读入很蛋疼,没好好学过java还真不知道要这么写,具体见代码
import java.math.*;
import java.util.*;
import java.io.*;
import java.util.*;
public class Main {
int M = 110;
int CD;
int fail[] = new int[M];
int Q[] = new int[M];
int ch[][] = new int[M][55];
int ID[] = new int[256];
int sz;
int flag[] = new int[M];
String DIC;
BigInteger dp[][] = new BigInteger[55][M];
BigInteger ans;
PrintStream out = System.out;
int m;
public void Init() {
fail[0] = 0;
flag[0] = 0;
Arrays.fill(ch[0], 0);
sz = 1;
for (int i = 0; i < DIC.length(); i++)
ID[DIC.charAt(i)] = i;
CD = DIC.length();
}
public void Insert(String s) {
int p = 0;
for (int i = 0; i < s.length(); i++) {
int c = ID[s.charAt(i)];
if (ch[p][c] == 0) {
Arrays.fill(ch[sz], 0);
flag[sz] = 0;
ch[p][c] = sz++;
}
p = ch[p][c];
}
flag[p] = 1;
}
void Construct() {
int head = 0, tail = 0;
for (int i = 0; i < CD; i++) {
if (ch[0][i] != 0) {
fail[ch[0][i]] = 0;
Q[tail++] = ch[0][i];
}
}
while (head != tail) {
int u = Q[head++];
for (int i = 0; i < CD; i++) {
int v = ch[u][i];
if (v != 0) {
Q[tail++] = v;
fail[v] = ch[fail[u]][i];
flag[v] += flag[fail[v]];
} else {
ch[u][i] = ch[fail[u]][i];
}
}
}
}
public void DP(){
for (int i = 0; i <= m; i++) {
for (int j = 0; j <= sz; j++) {
dp[i][j] = BigInteger.ZERO;
}
}
dp[0][0] = BigInteger.ONE;
for (int i = 0; i < m; i++) {
for (int j = 0; j < sz; j++)
if (dp[i][j].compareTo(BigInteger.valueOf(0)) == 1) {
for (int k = 0; k < CD; k++) {
if (flag[ch[j][k]] > 0 || flag[j] > 0)
continue;
dp[i + 1][ch[j][k]] = dp[i + 1][ch[j][k]].add(dp[i][j]);
}
}
}
ans = BigInteger.ZERO;
for (int i = 0; i < sz; i++)
ans = ans.add(dp[m][i]);
out.println(ans);
}
public void solve() {
int n, p ;
try {
BufferedReader cin = new BufferedReader(new InputStreamReader(System.in, "ISO-8859-1"));
String[] args = cin.readLine().split(" ");
n = Integer.parseInt(args[0]);
m = Integer.parseInt(args[1]);
p = Integer.parseInt(args[2]);
DIC = cin.readLine();
Init();
for (int i = 0; i < p; i++) {
String s=cin.readLine();
Insert(s);
}
Construct();
DP();
} catch(IOException e){
}
}
public static void main(String args[]) {
new Main().solve();
}
}
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include