概率题总汇
以前就见过不少求期望的题,题意很直白,但是却一直少不到思路做题
今天lcy老师推荐我看了zjut一位大牛的文章
http://bbs.zjut.com/viewthread.php?tid=1170233&extra=page%3D1
终于略知一二了,找几道概率题做做
http://acm.hdu.edu.cn/search.php?field=problem&key=2262
E(now) = (E(NEXT1) + E(NEXT2) +...+E(NEXTn))/n + 1
每个相邻点建方程,注意起点可以走到得边才能建方程,不然会导致无解
先floodfill找到起点可以走到得点,然后建方程,最后仍个高斯消元模板解把答案解出来
http://acm.zjut.edu.cn/ShowProblem.aspx?ShowID=1423
同上一道一摸一样的题
http://acm.zjut.edu.cn/ShowProblem.aspx?ShowID=1317
这个需要构造,相隔位子数的转换
想在相邻n,都向内飞的话n-2,都想外飞n+2,一个向左一个向右的话就保持n不变,所以有下列方程
E[n] = E[n+2]/4 + E[n-2]/4 + E[n]/2 + 1
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2619
此题极度郁闷,转移方程已经推出来了,却因为精度问题过不了
第四个sample我试了三个模板,出来的答案都不一样。。。。。
用java可过
http://acm.hdu.edu.cn/showproblem.php?pid=3058
上体升级版,变成了多串匹配,建Tire图的基础上进行转移
一样存在精度问题,用java可过
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2837
因为电梯有上有下,我索性就把楼的高度加倍 n = n * 2 - 2
那sample来说,0~10是向上的,10~20是向下的,20就是0,向上的话又变成1开始
在第7和第13层会碰到鬼(我从0层开始,所以每个量都要-1)
这样就可以得到转移方程
E[i] = E[(i+j)%n]/6 + 1
for
(i
=
0
; i
<
n ; i
++
) {
if (i == m || i == n - m) {
mat[i][i] = 1 ;
} else {
mat[i][i] = 6 ;
mat[i][n] = 6 ;
for (j = 1 ; j <= 6 ; j ++ ) {
mat[i][(i + j) % n] -- ;
}
}
}
http://acm.hdu.edu.cn/showproblem.php?pid=1204
if (i == m || i == n - m) {
mat[i][i] = 1 ;
} else {
mat[i][i] = 6 ;
mat[i][n] = 6 ;
for (j = 1 ; j <= 6 ; j ++ ) {
mat[i][(i + j) % n] -- ;
}
}
}
这题很早就开始想了,现在才会做,公式如下:
a = p * (1 - q);
b = q * (1 - p);
E[n] = E[n-1] * a + E[n+1] * b + E[n] * (1 - a - b);
E[0] = 0;
E[N+M] = 1;
这两道AC的代码都超短,应该是公式题。。没上边几道那么有意思。。。
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2949
http://acm.pku.edu.cn/JudgeOnline/problem?id=3682
献上第一次写的高斯消元模板
若返回时false则无解
/*
*************************************************
* mat里建好方程,增广矩阵 n*(n+1)
* 传入方程个数
* 答案保存在mat[i][i]中
************************************************* */
#include " stdio.h "
#include " string "
#define ab(a) (((a)>0)?(a):(-a))
#define maxn 100
#define eps 1e-10
double mat[maxn][maxn];
void swap( double & a, double & b) { double t = a;a = b;b = t;}
bool Gauss( int n) {
int i,j,row,idx;
double maxx,buf;
for (row = 0 ; row < n ; row ++ ) {
for (maxx = 0 ,i = row ; i < n ; i ++ )
if (ab(mat[i][row]) > maxx)
maxx = ab(mat[i][row]),idx = i;
if (maxx < eps) return false ;
if (idx != row)
for (j = 0 ; j <= n ; j ++ )
swap(mat[row][j],mat[idx][j]);
for (i = row + 1 ; i < n ; i ++ )
for (buf = mat[i][row] / mat[row][row],j = row; j <= n ; j ++ )
mat[i][j] -= buf * mat[row][j];
}
for (i = n - 1 ;i >= 0 ; i -- ) {
for (j = i + 1 ; j < n ; j ++ )
mat[i][n] -= mat[i][j] * mat[j][j];
mat[i][i] = mat[i][n] / mat[i][i];
}
return true ;
}
* mat里建好方程,增广矩阵 n*(n+1)
* 传入方程个数
* 答案保存在mat[i][i]中
************************************************* */
#include " stdio.h "
#include " string "
#define ab(a) (((a)>0)?(a):(-a))
#define maxn 100
#define eps 1e-10
double mat[maxn][maxn];
void swap( double & a, double & b) { double t = a;a = b;b = t;}
bool Gauss( int n) {
int i,j,row,idx;
double maxx,buf;
for (row = 0 ; row < n ; row ++ ) {
for (maxx = 0 ,i = row ; i < n ; i ++ )
if (ab(mat[i][row]) > maxx)
maxx = ab(mat[i][row]),idx = i;
if (maxx < eps) return false ;
if (idx != row)
for (j = 0 ; j <= n ; j ++ )
swap(mat[row][j],mat[idx][j]);
for (i = row + 1 ; i < n ; i ++ )
for (buf = mat[i][row] / mat[row][row],j = row; j <= n ; j ++ )
mat[i][j] -= buf * mat[row][j];
}
for (i = n - 1 ;i >= 0 ; i -- ) {
for (j = i + 1 ; j < n ; j ++ )
mat[i][n] -= mat[i][j] * mat[j][j];
mat[i][i] = mat[i][n] / mat[i][i];
}
return true ;
}