UVALive 3490 (LA 3940) || ZOJ 2619 Generator AC自动机(或KMP) + 整数高斯消元 + 数学期望

来源:互联网 发布:数据建模 开源 编辑:程序博客网 时间:2024/05/29 07:39

题目大意:

就是现在一个字符串生成器每次随机扔出前n(n <= 26)个大写英语字母的一个

将产生的字符连接起来成为其生成的字符串,如果它产生的字符串中有连续的一段出现了给定的禁止串,则生成停止

求停止时已经生成的字符串长度的期望


大致思路:

一开始果断用了AC自动机,后来发现KMP也就足够了

这个题建立方程组之后用Gauss消元不能用double的,容易产生误差...(因为误差跪了好多发之后改成整数版)

状态转移方程和细节见代码注释..


代码如下:

Result  :  Accepted     Memory  :  276 KB     Time  :  0 ms

/* * Author: Gatevin * Created Time:  2015/2/12 18:23:00 * File Name: Mononobe_Mitsuki.cpp */#include<iostream>#include<sstream>#include<fstream>#include<vector>#include<list>#include<deque>#include<queue>#include<stack>#include<map>#include<set>#include<bitset>#include<algorithm>#include<cstdio>#include<cstdlib>#include<cstring>#include<cctype>#include<cmath>#include<ctime>#include<iomanip>using namespace std;const double eps(1e-8);typedef long long lint;int n;char in[15];/* * 首先建立AC自动机得到状态转移图 * 用E[i]表示在转移图中的点i处到达目标状态需要的期望步数, 则E[0]即为解(root == 0) * 由于只有一个串记其结尾位置为AC自动机中的点L - 1长度为L的话 * 显然E[L - 1] = 0 (L为AC自动机上的总点数) * 对于0 <= i < L - 1有转移方程E[i] = ∑(E[next[i][j]] + 1) / n , (0 <= j < n) * L - 1 <= 12可以使用高斯消元求解复杂度O(L^3) AC自动机复杂度O(L) * 由于此题有误差,使用double的高斯消元求得E[0]后转long long误差太大不可行 * 需要用整数型的高斯消元 */struct Trie{    int next[15][26], fail[15];    bool end[15];    int L, root;    int var, equ;    lint a[15][15], x[15];    int newnode()    {        for(int i = 0; i < n; i++)            next[L][i] = -1;        end[L++] = 0;        return L - 1;    }    void init()    {        L = 0, equ = 0, var = 0;        root = newnode();        return;    }    void insert(char *s)    {        int now = root;        for(; *s; s++)        {            if(next[now][*s - 'A'] == -1)                next[now][*s - 'A'] = newnode();            now = next[now][*s - 'A'];        }        end[now] = 1;        return;    }    void build()    {        fail[root] = root;        queue <int> Q;        Q.push(root);        while(!Q.empty())        {            int now = Q.front();            Q.pop();            for(int i = 0; i < n; i++)                if(next[now][i] == -1)                    next[now][i] = now == root ? root : next[fail[now]][i];                else                {                    fail[next[now][i]] = now == root ? root : next[fail[now]][i];                    Q.push(next[now][i]);                }        }        return;    }    void getEquationSystem()    {        memset(a, 0, sizeof(a));        var = L;        for(int i = 0; i < L - 1; i++)        {            a[equ][i] += n;            for(int j = 0; j < n; j++)                a[equ][next[i][j]] -= 1;            x[equ++] = n;        }        a[equ][L - 1] = 1;        x[equ++] = 0;        return;    }    lint Gauss()//表示用double版本的高斯消元求解,最后还原成整数的方法因为误差跪掉了....    {        for(int i = 0; i < equ; i++)        {            int r = i;            while(r < equ && !a[r][i]) r++;            if(r != i)//找到第r列不是0的之后交换至r行            {                for(int j = 0; j < var; j++) swap(a[r][j], a[i][j]);                swap(x[r], x[i]);            }            for(int k = i + 1; k < equ; k++)                if(a[k][i])//将下面所有行的第i列变成0                {                    lint tmp = a[k][i];//两组互相乘上对面的第i列的数作差即可                    for(int j = i; j < var; j++) a[k][j] = a[k][j]*a[i][i] - tmp*a[i][j];                    x[k] = x[k]*a[i][i] - tmp*x[i];                }        }        //对剩下的三角矩阵递推求解        for(int i = equ - 1; i >= 0; i--)        {            for(int j = i + 1; j < var; j++)                x[i] -= x[j]*a[i][j];            x[i] /= a[i][i];        }        return x[0];    }};Trie AC;int main(){    int T;    scanf("%d", &T);    for(int cas = 1; cas <= T; cas++)    {        scanf("%d", &n);        AC.init();        scanf("%s", in);        AC.insert(in);        AC.build();        AC.getEquationSystem();        printf("Case %d:\n%lld\n", cas, AC.Gauss());        if(cas != T) printf("\n");    }    return 0;}


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 汽车围裙锈透了怎么办 万能胶水沾到手上怎么办 圆领体恤领口容易皱怎么办 上衣剪了个洞怎么办 上衣破了个洞怎么办 鸟屎腐蚀车漆怎么办 毛风衣叠久了怎么办 黑色的衣服沾毛怎么办 雪纺裙子弄上油怎么办 内衣买小了怎么办妙招 长裤衬衫裙邹了怎么办 100棉衬衣皱了怎么办? 短袖t恤袖口大了怎么办 短袖底下卷边了怎么办 棉质短袖衫缩水怎么办 纯棉t恤缩水了怎么办 t恤缩水变小了怎么办 衣服掉在雨棚上怎么办 车衣密码锁忘记密码怎么办 衣服的铁拉链弯怎么办 去旅行衣服皱了怎么办 衣服抽绳出来了怎么办 裤子的绑带掉了怎么办 网纱裙的边卷了怎么办 堵奶宝宝吸不通怎么办 棉麻裙子掉毛怎么办 10个月宝宝吃手怎么办 婴儿连体衣长了怎么办 冰丝面料变长了怎么办 t恤袖口大了怎么办 长袖t恤袖子长了怎么办 机打的扣子掉了怎么办 四个月宝宝头扁怎么办 鞋子前面穿翘了怎么办 休完产假没人带怎么办 休完产假孩子吃奶怎么办 巴布豆童鞋里面臭了到底怎么办 连体裤有点卡档怎么办 宝宝连体衣扣子掉了怎么办 买衣服被骂了怎么办? 把人车刮了跑了怎么办