LA3490 Generator(AC自动机或者kmp + dp +高斯消元)
来源:互联网 发布:c语言非空基本数据类型 编辑:程序博客网 时间:2024/06/03 16:09
【题意】
就是现在一个字符串生成器每次随机扔出前n(n <= 26)个大写英语字母的一个。将产生的字符连接起来成为其生成的字符串,如果它产生的字符串中有连续的一段出现了给定的禁止串,则生成停止。求停止时已经生成的字符串长度的期望
【解题方法】去网上看了一下题解,发现是dp+高斯小圆。于是开始自己推dp方程,觉得没问题了,开始写。那个转移那个地方,惯性写了个AC自动机!然后插入的时候才发现他妈只有一个字符串啊,要毛的AC自动机啊。kmp直接就搞下来了啊。TAT
来说一下这个题的解题方法吧!
首先建立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) *Trick 不能用double 的guass,因为会损失精度,直接WA
【AC 代码】我是真他妈蠢啊。
////Simpsons’ Hidden Talents//Created by just_sort 2016/9/28 18:41//Copyright (c) 2016 just_sort.All Rights Reserved//#include <set>#include <map>#include <queue>#include <stack>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>using namespace std;typedef long long LL;char s[20];int n;struct Acauotmata{ int root,L,ch[15][26],fail[15],cnt[15];//Acautomata int var,equ; LL a[15][15],x[15];//Guass equ个方程,var个变量 int newnode(){ memset(ch[L],-1,sizeof(ch[L])); cnt[L] = 0; return L++; } void init(){ L = equ = var = 0; root = newnode(); } int id(char c){ return c-'A'; } void insert(char *s){ int u = root; int len = strlen(s); for(int i = 0; i < len; i++){ if(ch[u][id(s[i])] == -1){ ch[u][id(s[i])] = newnode(); } u = ch[u][id(s[i])]; } cnt[u] = 1; } 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(ch[now][i] == -1){ ch[now][i] = now == root?root:ch[fail[now]][i]; } else{ fail[ch[now][i]] = now ==root?root:ch[fail[now]][i]; q.push(ch[now][i]); } } } } void getxishu() { 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][ch[i][j]] -= 1; } x[equ++] = n; } a[equ][L-1] = 1; x[equ++] = 0; } void debug(){ for(int i = 0; i < L; i++){ for(int j = 0; j < L-1; j++){ printf("%lld ",a[i][j]); } printf("%lld\n",x[i]); } printf("\n"); } LL Guass() { for(int i = 0; i < equ; i++){ int r = i; while(r < equ && !a[r][i]) r++; if(r != i){ 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]){ int tmp = a[k][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]; }}ac;int main(){ int T; scanf("%d",&T); for(int ks = 1; ks <= T; ks++){ scanf("%d",&n); ac.init(); scanf("%s",s); ac.insert(s); ac.build(); ac.getxishu(); //ac.debug(); printf("Case %d:\n",ks); printf("%lld\n",ac.Guass()); if(ks != T){ printf("\n"); } } return 0;}
0 0
- LA3490 Generator(AC自动机或者kmp + dp +高斯消元)
- UVALive 3490 Generator(AC自动机+dp+高斯消元)
- UVaLive 3490 - Generator (AC自动机 期望DP 高斯消元)
- LA3490 Generator
- UVALive 3490 (LA 3940) || ZOJ 2619 Generator AC自动机(或KMP) + 整数高斯消元 + 数学期望
- KMP算法 AC自动机
- KMP && AC自动机模板
- woj1572 Cyy and Fzz KMP / AC自动机 + DP
- ZOJ 2619 Generator (概率、AC自动机、高斯消元)
- hdu4758 AC自动机+dp
- AC自动机 + DP小结
- AC自动机+DP+hdu2296
- hdu2457 AC自动机+DP
- hdu2296(AC自动机+DP)
- hdu2296 AC自动机+DP
- uvalive4842(AC自动机+DP)
- poj3691(ac自动机+dp)
- hdu3689(ac自动机+dp)
- Service和Activity之间的交互
- sizeof & strlen
- 51单片机矩阵键盘库
- Servlet学习笔记
- 产品入库的PV操作
- LA3490 Generator(AC自动机或者kmp + dp +高斯消元)
- struts2使用cookie详解
- java环境搭建系列:JDK从下载安装到简单使用
- uva11181(概率)
- java基础:接口。
- Python——map()/reduce()
- LeetCode---35. Search Insert Position(查找插入位置)
- 数据结构
- 跨进程的通信 [IPC]