poj 1625 Censored! AC自动机+DP +高精度 + C艹 + java

来源:互联网 发布:手机时间不与网络同步 编辑:程序博客网 时间:2024/05/16 12:01

挺简单的一道题,搞了很久,主要是用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();}}




c++代码

#include <cstdio>#include <cstdlib>#include <string>#include <climits>#include <iostream>   #include <vector>#include <set>#include <cmath>#include <cctype>#include <algorithm>#include <sstream>#include <map>#include <cstring>#include <queue>using namespace std;const int M = 110;int CD;int fail[M];int Q[M];int ch[M][55];int ID[500];int val[M];int sz;char S[55];int n,m,p;void Init(){fail[0]=0;memset(ch[0],0,sizeof(ch[0]));sz=1;for(int i=0;i<n;i++) ID[S[i]]=i;CD = n;}void Insert(char *s){int p=0;for(;*s;s++){int c=ID[*s];if(!ch[p][c]){memset(ch[sz],0,sizeof(ch[sz]));val[sz]=0;ch[p][c]=sz++;}p=ch[p][c];}val[p]=1;}void Construct(){int  *s=Q,*e=Q;for(int i=0;i<CD;i++){if(ch[0][i]){fail[ch[0][i]] = 0;*e++ = ch[0][i];}}while(s!=e){int u = *s++;for(int i=0;i<CD;i++){int &v = ch[u][i];if(v){*e++ = v;fail[v]=ch[fail[u]][i];val[v]|=val[fail[v]];} else  {v=ch[fail[u]][i];}}}}struct Bignum{int len;int num[105];void init(){len=1;memset(num,0,sizeof(num));}};Bignum dp[55][105],ans;Bignum add(Bignum a,Bignum b){Bignum c;c.init();int i;for(i=0;i<a.len||i<b.len;i++){c.num[i]=a.num[i]+b.num[i];}int jin=0;for(i=0;i<a.len||i<b.len;i++){int tmp=c.num[i]+jin;c.num[i]=tmp%10;jin=tmp/10;}if(jin!=0){c.num[i]=jin;i++;}c.len=i;return c;}bool used[55][105];void solve(){memset(used,false,sizeof(used));used[0][0]=true;for(int i=0;i<=m;i++){for(int j=0;j<sz;j++){dp[i][j].len=1;dp[i][j].init();}}dp[0][0].num[0]=1;for(int i=0;i<m;i++) {for(int j=0;j<sz;j++) if(used[i][j] && !val[j]){for(int k=0;k<CD;k++)  if(!val[ch[j][k]]){dp[i+1][ch[j][k]]=add(dp[i+1][ch[j][k]],dp[i][j]);used[i+1][ch[j][k]]=1;}}}ans.init();for(int i=0;i<sz;i++){ans=add(ans,dp[m][i]);}for(int i=ans.len-1;i>=0;i--){printf("%d",ans.num[i]);}puts("");}int main() {char s[20];while(scanf("%d%d%d",&n,&m,&p)!=EOF){scanf("%s",S);Init();for(int i=0;i<p;i++){scanf("%s",s);Insert(s);}//printf("sz=%d\n",sz);Construct();solve();}return 0;}



原创粉丝点击