• 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 }
    View Code
  • 相关阅读:
    Flink Application Development DataStream API Execution Mode (Batch/Streaming)- Flink应用程序开发DataStream API执行模式(批/流)
    Flink Application Development DataStream API Overview
    Flink Concept Stateful Stream Processing -Flink概念有状态流处理
    Hdfs原理
    Leetcode 763 划分字母区间
    406. 根据身高重建队列
    贝叶斯统计概要(待修改)
    蒙特卡罗方法
    马尔科夫链蒙特卡罗方法(MCMC)
    Leetcode452. 用最小的箭引爆气球
  • 原文地址:https://www.cnblogs.com/hzf-sbit/p/3879224.html
Copyright © 2020-2023  润新知