题意
有 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. 作业七:团队项目——Alpha版本冲刺阶段004

    今日进展:我们的扫雷基本界面已经差不多了,准备开始编写内部代码. 今日安排:做好界面,准备开始代码编写.

  2. linux -a 到 -z 的意义

    shell if判断中常用的也就是绿色部分,尾部部分越看越不懂.从百度文库转载. [ -a FILE ] 如果 FILE 存在则为真. [ -b FILE ] 如果 FILE 存在且是一个块特殊文件则 ...

  3. C++ 之 class 的思考

    工作多年,突然发现c++这么多年都是零散记录了些自己对C++的反思,没有做过任何的文字记录表示遗憾. 看到很多小伙也都在写技术博客,那我自己也就写一写自己的一些 思考吧! C++的基本类这个东西,想必 ...

  4. JAVA时间格式转换大全

    import java.text.*; import java.util.Calendar; public class VeDate { /** * 获取现在时间 * * @return 返回时间类型 ...

  5. MySQL主从复制与读写分离

    MySQL主从复制(Master-Slave)与读写分离(MySQL-Proxy)实践 Mysql作为目前世界上使用最广泛的免费数据库,相信所有从事系统运维的工程师都一定接触过.但在实际的生产环境中, ...

  6. Android Fragment (一)

    1.Fragment的产生与介绍   Android运行在各种各样的设备中,有小屏幕的手机,超大屏的平板甚至电视.针对屏幕尺寸的差距,很多情况下,都是先针对手机开发一套App,然后拷贝一份,修改布局以 ...

  7. #define用法解析

    #define Add(a,b) a+b; 在一般使用的时候是没有问题的,但是如果遇到如: c * Add(a,b) * d 的时候就会出现问题,代数式的本意是a+b然后去和c,d相乘,但是因为使用了 ...

  8. iOS交互WebService(cxf框架)

    公司后台java用的cxf框架,说是iOS.Android.web客户端都可以通用,但是我还是第一次遇到,所以做的时候遇到了不小的坑.下面总结下我开发中遇到的问题以及解决方案: 首先,后台提供了一份接 ...

  9. Linux 下安装Source Insight

    第一步: 安装Wine 下面跟大家分享一下如何在Ubuntu 12.04上安装Wine 1).添加PPA --  PPA:表示 Personal Package Archives,也就是个人软件包集. ...

  10. 进程间通信 System V 消息队列

    1.msgget (key_t ket,int flag) ; //创建一个新的消息队列或者访问一个已存在的消息队列 2.msgsnd(int msid, const void *ptr ,size_ ...