hdu 3992(AC自动机 + 高斯消元 + 求期望(好题))
来源:互联网 发布:pc客户端制作软件 编辑:程序博客网 时间:2024/05/14 23:58
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3992
题意是说26个字母一定概率随机出现添加到当前字符串的尾部, 给出若干模式串求该字符串中出现任一模式串的期望的长度, 根据模式串建立AC自动机, 一个字符串对应的是自动机上的一系列状态转移, 所以题目就变成了那一类求从图上某个点出发到达指定点的期望走过的步数的题目, 只不过这里的图就是trie图,由于有fail指针所以图上有环所以需要用到高斯消元求解。
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <cstdlib>#include <cmath>using namespace std;const double eps = 1e-8;const int N = 1005;const int C = 26;int Map[256];int c;double A[205][205];bool inf[205];double prob[C];void init() {for (int i = 0; i < C; i++) {Map[i + 'a'] = i;}}void gauss() {int i, j, k, r;for (i = 0; i < c; i++) {r = i;for (j = i + 1; j < c; j++)if (fabs(A[j][i]) > fabs(A[r][i])) r = j;if (fabs(A[r][i]) < eps) continue;if (r != i) for (j = 0; j <= c; j++) swap(A[r][j], A[i][j]);for (k = 0; k < c; k++) if (k != i)for (j = c; j >= i; j--)A[k][j] -= A[k][i] / A[i][i] * A[i][j];}}struct AC {struct Node {bool out;int id;Node* ch[C];Node* fail;void init() {out = 0;memset(ch, 0, sizeof(ch));fail = 0;}};Node* root, * null, * it;Node* head[N], * que[N];Node D[N * 10];int sz;Node* get_Node() {it->init();head[sz] = it;it->id = sz++;it++;return it - 1;}void init() {it = D;sz = 0;null = new Node;null->init();root = get_Node();for (int i = 0; i < C; i++)null->ch[i] = root;root->fail = null;}void add(char* str) {Node* cur = root;for (int i = 0; str[i]; i++) {if (!cur->ch[Map[str[i]]]) cur->ch[Map[str[i]]] = get_Node();cur = cur->ch[Map[str[i]]];}cur->out = 1;}void set_fail() {int st = 0, ed = 0;que[ed++] = root;while (st < ed) {Node* cur = que[st++];for (int i = 0; i < C; i++) {Node* t = cur->fail;if (!cur->ch[i]) {while (t != null && !t->ch[i]) t = t->fail;cur->ch[i] = t->ch[i];continue;}que[ed++] = cur->ch[i];while (t != null && !t->ch[i]) t = t->fail;cur->ch[i]->fail = t->ch[i];cur->ch[i]->out |= t->ch[i]->out;} } }void gao() {c = sz;for (int i = 0; i < sz; i++)fill(A[i], A[i] + sz + 1, 0);for (int i = 0; i < sz; i++) {A[i][i] = 1;if (head[i]->out) {A[i][sz] = 0;continue;}A[i][sz] = 1;for (int j = 0; j < C; j++) {int t = head[i]->ch[j]->id;A[i][t] -= prob[j];}}gauss();memset(inf, 0, sizeof(inf));for (int i = c - 1; i >= 0; i--) {if (fabs(A[i][i]) < eps && fabs(A[i][c]) > eps) inf[i] = 1;for (int j = i + 1; j < c; j++) if (fabs(A[i][j]) > eps && inf[j]) inf[i] = 1;}if (inf[0]) puts("Infinity");else {if (fabs(A[0][0]) < eps)puts("0.000000");elseprintf("%.6f\n", A[0][sz] / A[0][0]);}}}ac;char str[100];int main() {int n;init();while (~scanf("%d", &n)) {for (int i = 0; i < 26; i++) {scanf("%lf", &prob[i]);}ac.init();for (int i = 0; i < n; i++) {scanf("%s", str);ac.add(str);}ac.set_fail();ac.gao();}return 0;}
- hdu 3992(AC自动机 + 高斯消元 + 求期望(好题))
- hdu 3962 Microgene (ac自动机+矩阵优化(好题))
- UVaLive 3490 - Generator (AC自动机 期望DP 高斯消元)
- hdu 5955 (ac自动机+高斯消元 )
- hdu 2222(AC自动机入门题)
- hdu 2222(ac自动机入门题)
- HDU 3065 (AC自动机水题)
- hdu 3065(ac自动机)
- HDU 2222 (AC自动机)
- Hdu 2222(AC 自动机)
- HDU 3065 (AC自动机)
- hdu 2896 (AC自动机)
- HDU 2222 (AC自动机)
- hdu 6208 (ac自动机)
- HDU 4035 dp求期望 好题
- NEFU 1267 挑战字符串 (AC自动机+贪心)好题
- AC自动机构造字符串(好)poj2778
- HDU 3695:Computer Virus on Planet Pandora(AC自动机裸题,数组实现AC自动机)
- iOS: NSNotificationCenter的方法addObserverForName:object:queue:usingBlock:
- ubuntu 没有显示器 vnc登陆 分辨率设置
- VS2010+Opencv-2.4.0的配置攻略 & Win7x64+VS2012+OpenCV2.4.3+CMake2.8.10+TBB41重编译OpenCV
- java正则表达式
- 工作零散记忆_002
- hdu 3992(AC自动机 + 高斯消元 + 求期望(好题))
- 三角形外接圆圆心公式
- 三屏版知识竞赛类软件的开发需求分析及技术构思
- Node.js操作mongodb数据库
- Android屏幕适配
- LOG4J
- iOS: NSNotificationCenter的方法postNotification:
- Cocos-2dx 2.1.4 如何创建跨平台工程
- Linux入门学习-ubuntu基本命令_第二章