题意
有 N≤10 个人,每个猜一个长度为L≤10的由1−6构成的序列,保证序列两两不同。
不断地掷骰子,直到后缀与某人的序列匹配,则对应的人获胜。
求每个人获胜的概率。

思路:
建立trie图,跑高斯消元.
高斯消元每个点的意义是:
第i行第j列的值为x 有概率x从点j转移过来

 const double eps = 1e-;
const int SIGMA_SIZE = ;
const int MAXNODE = ; int ch[MAXNODE][SIGMA_SIZE];
int f[MAXNODE];
int sz; void insert(int* P, int len, int v) {
int u = ;
for (int i = ; i < len; i++) {
int c = P[i];
if (!ch[u][c]) {
memset(ch[sz], , sizeof(ch[sz]));
ch[u][c] = sz++;
}
u = ch[u][c];
}
} void getFail() {
f[] = ;
queue<int> q;
for (int c = ; c < SIGMA_SIZE; c++) {
int u = ch[][c];
if (u) {
q.push(u);
f[u] = ;
}
}
while (!q.empty()) {
int r = q.front(); q.pop();
for (int c = ; c < SIGMA_SIZE; c++) {
int u = ch[r][c];
if (!u) {
ch[r][c] = ch[f[r]][c];
continue;
}
q.push(u);
int v = f[r];
while (v && !ch[v][c]) v = f[v];
f[u] = ch[v][c];
}
}
} //double的高斯消元
double a[MAXNODE][MAXNODE], x[MAXNODE];//方程的左边的矩阵和等式右边的值,求解之后x存的就是结果
int equ, var;//方程数和未知数个数
int Gauss()
{
for (int k=, col=; k<equ && col<var; k++, col++)
{
int max_r=k;
for (int i=k+; i<equ; i++)
if (fabs(a[i][col]) > fabs(a[max_r][col])) max_r=i;
if (fabs(a[max_r][col]) < eps) return ;
if (k != max_r)
{
for (int j = col; j < var; j++) swap(a[k][j], a[max_r][j]);
swap(x[k], x[max_r]);
}
x[k] /= a[k][col];
for (int j=col+; j<var; j++) a[k][j] /= a[k][col];
a[k][col] = ;
for (int i=; i<equ; i++)
if (i != k)
{
x[i] -= x[k] * a[i][k];
for(int j=col+; j<var; j++) a[i][j]-=a[k][j]*a[i][col];
a[i][col] = ;
}
}
return ;
} const int maxn = ;
int n, len;
int peo[maxn][maxn];
bool end[MAXNODE];
vector<int> G[MAXNODE]; void init()
{
memset(f, , sizeof(f));
memset(ch, , sizeof(ch));
memset(a, , sizeof(a));
memset(end, , sizeof(end));
memset(x, , sizeof(x)); sz = ;
scanf("%d%d", &n, &len);
for (int i = ; i <= n; i++)
{
for (int j = ; j < len; j++)
{
scanf("%d", &peo[i][j]);
}
insert(peo[i], len, i);
end[sz - ] = true;
}
for (int i = ; i < sz; i++)
{
G[i].clear();
}
} void getGraph()
{
getFail();
for (int i = ; i < sz; i++)
{
if (!end[i])
{
for (int j = ; j < ; j++)
{
int t = ch[i][j];
G[t].push_back(i);
}
}
}
} void solve()
{
getGraph();
equ = var = sz;
for (int i = ; i <sz; i++)
{
for (auto j : G[i])
{
a[i][j] += 1.0/;
}
a[i][i] -= ;
}
x[] = -; Gauss(); vector<double> ans;
for (int i = ; i < sz; i++)
{
if (end[i])
{
ans.push_back(x[i]);
}
}
for (int i = ; i < ans.size() - ; i++)
{
printf("%.6f ", ans[i]);
}
printf("%.6f\n", *ans.rbegin()); } int main()
{
int T;
scanf("%d", &T);
while (T--)
{
init();
solve();
}
return ;
}

HDU 5966 Guessing the Dice Roll的更多相关文章

  1. HDU 5955 Guessing the Dice Roll

    HDU 5955 Guessing the Dice Roll 2016 ACM/ICPC 亚洲区沈阳站 题意 有\(N\le 10\)个人,每个猜一个长度为\(L \le 10\)的由\(1-6\) ...

  2. hdu 5955 Guessing the Dice Roll 【AC自动机+高斯消元】

    hdu 5955 Guessing the Dice Roll [AC自动机+高斯消元] 题意:给出 n≤10 个长为 L≤10 的串,每次丢一个骰子,先出现的串赢,问获胜概率. 题解:裸的AC自动机 ...

  3. hdu5955 Guessing the Dice Roll【AC自动机】【高斯消元】【概率】

    含高斯消元模板 2016沈阳区域赛http://acm.hdu.edu.cn/showproblem.php?pid=5955 Guessing the Dice Roll Time Limit: 2 ...

  4. 2016ACM/ICPC亚洲区沈阳站H - Guessing the Dice Roll HDU - 5955 ac自动机+概率dp+高斯消元

    http://acm.hdu.edu.cn/showproblem.php?pid=5955 题意:给你长度为l的n组数,每个数1-6,每次扔色子,问你每个串第一次被匹配的概率是多少 题解:先建成ac ...

  5. [HDU5955]Guessing the Dice Roll

    Problem Description There are N players playing a guessing game. Each player guesses a sequence cons ...

  6. 【HDU5955】Guessing the Dice Roll/马尔科夫

    先从阿里机器学习算法岗网络笔试题说起:甲乙两人进行一个猜硬币的游戏.每个人有一个目标序列,由裁判来抛硬币.谁先得到裁判抛出的一串连续结果,谁赢. 甲的目标序列是正正正,乙的目标序列是反正正.那么如果裁 ...

  7. 【AC自动机】【高斯消元】hdu5955 Guessing the Dice Roll

    http://blog.csdn.net/viphong/article/details/53098489 我有一点不是很懂,这样算出来转移到AC自动机根节点的概率是一个远大于1的数. 按我的理解,因 ...

  8. 【HDOJ5955】Guessing the Dice Roll(概率DP,AC自动机,高斯消元)

    题意: 有n个人,每个人有一个长为L的由1~6组成的数串,现在扔一个骰子,依次记录扔出的数字,如果当前扔出的最后L个数字与某个人的数串匹配,那么这个人就算获胜,现在问每个人获胜的概率是多少. n,l& ...

  9. hdu 4586 Play the Dice 概率推导题

    A - Play the DiceTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/contest/ ...

随机推荐

  1. 课程笔记:——Javascript 中的预解释1

    1.预解释(变量提升):在当前作用域下,JS代码执行之前,浏览器首先会把所有带var和function关键字的进行提前的声明或者定义var num = 12;声明(declare): var num; ...

  2. Linux网络编程(简单的时间获取服务器)

    1.一个简单的服务器时间获取程序 服务器和客户端采用UDP通信的方式,来编写一个简单的时间获取应用. 把过程大致理顺一下,首先是服务器端的编写,使用的是迭代的方式,没有并发 先创建一个socket而后 ...

  3. C#方法参数传递机制

    1:value(值传递).ref(引用传递).out(输出传递) ref和out使用效果上面是等效的,它们的区别在于:参数标记为ref,那么必须在调用函数之前初始化参数的值:参数标记为out,调用函数 ...

  4. c++unsigned char的输出问题

    unsigned char的范围是0~255,在用cout输出的时候要显示数字的话记得进行int的强制转化才可以,否则都是输出的字符,除此之外的所有比较转换成整数在做比较吧 除此之外,在最近的项目里由 ...

  5. 好用的开源爬虫 jsoup

    中文Api http://www.open-open.com/jsoup/ 英文Api https://jsoup.org/

  6. Robot_bfs

    Description The Robot Moving Institute is using a robot in their local store to transport different ...

  7. CoInitialize浅析一

    大家都知道程序中若要使用COM组件则必须要先调用CoInitialize,该函数主要是用来初始化COM运行环境.但这个函数的作用域是以线程为单位还是以进程为单位呢?也许大家已经通过测试程序摸索出答案, ...

  8. nginx日志分析利器GoAccess

    面试的时候一定会被面到的问题是:给出web服务器的访问日志,请写一个脚本来统计访问前10的IP有哪些?访问前10的请求有哪些?当你领略过goaccess之后,你就明白,这些问题,除了考验你的脚本背诵记 ...

  9. the django travel(two)

    一:django路由系统: 注意:我们在urls.py中 定义url的时候,可以加$和不加$,区别的是:加$正则匹配的时候,比如:'/index/$'只能匹配'/index/'这样的url 不能匹配' ...

  10. 【JS】HTMLprop与attr的区别

    与prop一样attr也可以用来获取与设置元素的属性.区别在于,对于自定义属性和选中属性的处理.选中属性指的是 checked,selected 这2种属性1. 对于自定义属性 attr能够获取,pr ...