201. Non Absorbing DFA

题意好难看懂的说。。。

  有限状态自动机DFA是这么一个有序组<Σ, U, s, T, phi>;Σ代表输入字符集,表示此自动机的工作范围;U代表所有的状态集合;s是初始状态;T是最终状态;phi代表转移函数,定义为phi : U × Σ → U。

  利用DFA进行字符串识别是要你做这么一件事情:The input of the automation is the string α over Σ. Initially the automation is in state s. Each step it reads the first character c of the input string and changes its state to phi(u, c) where u is the current state. After that the first character of the input string is removed and the step repeats. If when its input string is empty the automation is in the terminal state, it is said that it accepts the initial string α, in the other case it rejects it.

  然后无聊的出题人给他加入了一个,b的东西:Nonabsorbing Edges,直译不吸收边。Define function χ : U × Σ → {0, 1}. When making a transition from some state u with some character c, the leading character is removed from the input string only if χ(u, c) = 0. If χ(u, c) = 1, the input string is kept intact and next transition is performed with the new state and the same character.

  称这样的DFA为NADFA。

  NADFA接受字符串的条件是:such automation accepts some string α if after a number of steps it transits to the terminal state and the input string becomes empty.

  输入:第一行是字符集Σ。下来一行是k,表示状态数量。下一行第一个数字S代表初始状态,第二个数字L代表结束状态的数量,然后是L个数字,代表结束状态的编号。然后是一个k * |Σ|的矩阵,代表函数phi。然后再是一个同样大小的矩阵,代表函数X。最后是N。

  题目就是要你求能被此,b形式下的DFA(NADFA)接受的长度为N的字符串数量。



竟然是ASC#2的A题!!!
然后发现SGU200~2**都是ASC的原题。。不忍直视了。。以我的智商看来SGU都刷不了了。。
不过SGU200题说到做到,决不放弃!BZOJ用来专门练一些算法。

怎么搞??

DP是很显然的。用f[i][j]表示匹配到第i位时处在状态j的字符串数量。由于不可吸收边的存在,可以使用记忆化搜索预处理出状态的直接转移。

要用到高精度。。。压位大法好。。。

  1 //{HEADS
  2 #define FILE_IN_OUT
  3 #include <cstdio>
  4 #include <cstring>
  5 #include <cstdlib>
  6 #include <cmath>
  7 #include <ctime>
  8 #include <algorithm>
  9 #include <iostream>
 10 #include <fstream>
 11 #include <vector>
 12 #include <stack>
 13 #include <queue>
 14 #include <deque>
 15 #include <map>
 16 #include <set>
 17 #include <bitset>
 18 #include <complex>
 19 #include <string>
 20 #define REP(i, j) for (int i = 1; i <= j; ++i)
 21 #define REPI(i, j, k) for (int i = j; i <= k; ++i)
 22 #define REPD(i, j) for (int i = j; 0 < i; --i)
 23 #define STLR(i, con) for (int i = 0, sz = con.size(); i < sz; ++i)
 24 #define STLRD(i, con) for (int i = con.size() - 1; 0 <= i; --i)
 25 #define CLR(s) memset(s, 0, sizeof s)
 26 #define SET(s, v) memset(s, v, sizeof s)
 27 #define mp make_pair
 28 #define pb push_back
 29 #define PL(k, n) for (int i = 1; i <= n; ++i) { cout << k[i] << ‘ ‘; } cout << endl
 30 #define PS(k) STLR(i, k) { cout << k[i] << ‘ ‘; } cout << endl
 31 using namespace std;
 32 void FILE_INIT(string FILE_NAME) {
 33 #ifdef FILE_IN_OUT
 34 #ifndef ONLINE_JUDGE
 35     freopen((FILE_NAME + ".in").c_str(), "r", stdin);
 36     freopen((FILE_NAME + ".out").c_str(), "w", stdout);
 37 #endif
 38 #endif
 39 }
 40 typedef long long LL;
 41 typedef double DB;
 42 typedef pair<int, int> i_pair;
 43 const int INF = 0x3f3f3f3f;
 44 //}
 45
 46 const int maxn = 1000 + 10;
 47 const int maxl = 100 + 10;
 48 const int maxm = 60 + 5;
 49 const int maxc = 27;
 50 const int base = 1000000000;
 51
 52 char sigma[maxc];
 53 int Snum, Size, S, k, L, n;
 54 int teminal_state[maxn], phi[maxn][maxc], chi[maxn][maxc], trans[maxn][maxc];
 55
 56 struct big_int {
 57     int d[maxl];
 58     int len;
 59     big_int() {
 60         CLR(d);
 61         len = 1;
 62     }
 63     big_int &operator += (const big_int &a) {
 64         len = max(len, a.len);
 65         REP(i, len) {
 66             d[i] += a.d[i];
 67             if(base < d[i]) {
 68                 d[i + 1] += d[i] / base;
 69                 d[i] %= base;
 70             }
 71         }
 72         for(; 0 < d[1 + len]; ++len);
 73         return *this;
 74     }
 75     void print() {
 76         printf("%d", d[len]);
 77         for(int i = len - 1; 0 < i; --i) {
 78             printf("%09d", d[i]);
 79         }
 80         puts("");
 81     }
 82 }f[maxn][maxm];
 83
 84 void dfs(int u, int c) {
 85     if(chi[u][c] == 0) {
 86         trans[u][c] = u;
 87     }
 88     if(trans[u][c]) {
 89         return;
 90     }
 91     trans[u][c] = -1;
 92     dfs(phi[u][c], c);
 93     trans[u][c] = trans[phi[u][c]][c];
 94 }
 95
 96 int main() {
 97     FILE_INIT("201");
 98
 99     scanf("%s", sigma);
100     Size = strlen(sigma);
101     scanf("%d", &k);
102     scanf("%d %d", &S, &L);
103     REP(i, L) {
104         scanf("%d", &teminal_state[i]);
105     }
106     REP(i, k) {
107         REP(j, Size) {
108             scanf("%d", &phi[i][j]);
109         }
110     }
111     REP(i, k) {
112         REP(j, Size) {
113             scanf("%d", &chi[i][j]);
114         }
115     }
116     scanf("%d", &n);
117     REP(i, k) {
118         REP(j, Size) {
119             if(!trans[i][j]) {
120                 dfs(i, j);
121             }
122         }
123     }
124     f[S][0].d[1] = 1;
125     REPI(i, 0, n - 1) {
126         REP(j, k) {
127             REP(c, Size) {
128                 if(trans[j][c] > 0) {
129                     f[phi[trans[j][c]][c]][i + 1] += f[j][i];
130                 }
131             }
132         }
133     }
134     big_int ans;
135     REP(i, L) {
136         ans += f[teminal_state[i]][n];
137     }
138     ans.print();
139
140     return 0;
141 }

201. Non Absorbing DFA,布布扣,bubuko.com

时间: 2024-12-20 23:53:20

201. Non Absorbing DFA的相关文章

sgu-201 Non Absorbing DFA

题目大意: 给你一个字符串,表示拥有的字符为长度L,即操作的种类L ,然后给你一个无向图,有n个顶点,标号从1~n,之后输入一个S,表示起点,即你一开始所在的位置,然后给你一个集合Σ,先输入元素个数,然后输入包含的元素有哪些.然后再给你一个数N,表示操作的字符串长度.最后停留的点必须在Σ中. 之后输入一个n*L的矩阵,第i行第j列表示在点号为i的点上进行字符操作 j 将会到达的点,记为change[ i ][ j ]. 之后又是一个n*L的矩阵,第i行第j列表示在点号为i的点上进行字符操作 j

CocoSourcesCS 3

1 /*---------------------------------------------------------------------- 2 Compiler Generator Coco/R, 3 Copyright (c) 1990, 2004 Hanspeter Moessenboeck, University of Linz 4 extended by M. Loeberbauer & A. Woess, Univ. of Linz 5 with improvements b

AC自动机- 自我总结

AC自动机算法总结  No.1 What's Aho-Corasick automaton? 一种多模式串匹配算法,该算法在1975年产生于贝尔实验室,是著名的多模匹配算法之一. 简单的说,KMP用来匹配一个模式串:但如果现在有多个模式串需要在同一篇文章中出现,现在就需要Aho-Corasick automaton算法了. 不要天真的以为AC自动机为auto-Accept,虽然他能让你AC一些题. No.2 My Understanding About Aho-Corasick automato

ASC(2)A(大数+图论DP)

Non Absorbing DFA Time Limit: 10000/5000MS (Java/Others)Memory Limit: 128000/64000KB (Java/Others) SubmitStatisticNext Problem Problem Description In the theory of compilers and languages finite state machines, also known as finite automata are widel

利用子集构造法实现NFA到DFA的转换

概述 NFA非有穷自动机,即当前状态识别某个转换条件后到达的后继状态不唯一,这种自动机不便机械实现,而DFA是确定有限状态的自动机,它的状态转换的条件是确定的,且状态数目往往少于NFA,所以DFA能够比较方便的机械实现且识别能力方面也和NFA相当.本次实验采用子集构造法来实现不带空弧的由NFA到DFA的转换. 子集构造法的算法如下: 设NFA为M=(K,Σ,f,S0,Z),则构造相应的DFA  M′=(Q,Σ,f′,I0,F)①取I0=S0:②对于状态集Q中任一尚未标记的状态qi={Si1,Si

词法分析器--DFA(c++实现)

语言名为TINY 实例程序: begin var x,y:interger; x:=10; read(x); if y<0 then x:=x-y; x:=x+y; write(x); end TINY语言扫描程序的DFA: 代码 //ExplLexicalAnalyzer.h #ifndef EXPLLEXICALANALYZER_H #define EXPLLEXICALANALYZER_H #define MAXTOKENLEN 40 #define MAXRESERVED 13 type

azure云迁移后expdp报错ORA-01110: data file 201: &#39;/home/oradata/powerdes/temp01.dbf&#39;

1,expdp的时候报错: 在idc的oracle服务器上正常导入导出都ok的,但是到了azure云上就出故障了: [[email protected] oracle]$ expdp \'powerdesk/testcrmfile\' directory=DIR_DUMP tables=bis_floor,bis_shop,bis_shop_conn,bis_store,bis_cont dumpfile=zhengyin.qu_bak_$(date +%Y%m%d)_02.dmp Export

RQNOJ 201 奥运大包围:LIS + 拼链成环

题目链接:https://www.rqnoj.cn/problem/201 题意: 开始时n(n<=1000)个人手拉手围成一个圈. 后来这些人中的一些按顺序向里面出圈形成一个新圈.从而使原圈形成一个从高到低,最低与最高连接的圈. 新圈重复相同的操作,直到没有人要出圈为止. 问最少要形成多少个这样的圈. 题解: (1)拼链成环: 对于一个环,可以用两条由环拆开的链拼在一起表示. 例如:有一个环为"1,2,3,4"(1和4连在一起),则可以表示为"1,2,3,4,1,2,

过滤敏感字DFA JAVA实现

package com.member.schedule; import java.io.UnsupportedEncodingException; import java.nio.ByteBuffer; import java.nio.charset.Charset; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author 徐良永 * @Date 2011-10-1