寒假真是极度荒废的,想补一补自己的概率方面的知识,感觉也没很好的补,只是把概率dp和高斯消元的一些东西搞懂了,难的也不会做。
什么期望的线性递推啊,概率公式,高深的基本都没学
lightoj 1027
这是以前碰到的老概率题了,当年压根不会,现在会了
有n个门让你选,每个门有一个数字,正数代表x分钟后出去,负数代表x分钟后回到起点重新开始
然后问你出去的时间期望是多少分钟
这题就是把正负时间统计一下,你每次选择出去的概率是pos/n,回去的概率是neg/n,然后你出去的平均时间是正数加起来的平均值,回去的时间是负数加起来的平均值,然后类似正常的求期望就好了,公式推导化简一下,得到最后的答案就行了
AC代码:http://paste.ubuntu.net/15157341/
lightoj 1030
这题应该是飞行棋,然后每个位置上有一个数字,6面骰子,问你从1走到n,走过的数的和的期望
概率dp求期望,一般要倒着dp,为什么呢,dp[i]表示从i走到n的期望,因为你从i走到i+1,i+2,。。。i+6,i有1/6的概率转移到比如i+1,然后得到dp[i+1],所以dp[i]+=1/6(dp[i+1]+dp[i+2]+...+dp[i+6])。如果不满6格不一定是1/6
AC代码:http://paste.ubuntu.net/15157399/
lightoj 1038
给你一个数n,然后从他的因子中选择一个d,然后得到n/d,然后还是这样操作,问你得到1需要的次数的期望
dp[i]=1+(sigma(dp[i/j]))/g[i]; j是i的因子,g[i]是i的因子的个数
然后j可能等于1,所以需要化简这个公式,把dp[i]移到一侧,然后得到结果,用递归写就能解决
AC代码:http://paste.ubuntu.net/15157453/
lightoj 1079
这题是你去抢银行,然后被抓的概率小于p的话就是安全,然后告诉你每个银行的钱和被抓的概率,求不被抓的情况下拿到最多的钱
这个很明显就是个背包啊,但是状态很容易想错
首先是被抓的概率不能相乘,不然你被抓的概率是越来越小,也不能想加,应该是不被抓的概率相乘,其次我傻逼的把概率当作下标来做,然后一直跪,毕竟没告诉我精度是多少
其实应该dp[i]表示抢到i个钱的时候不被抓的最大概率,然后dp[i]=max(dp[i-j]*(1-p));
AC代码:http://paste.ubuntu.net/15157500/
lightoj 1104
一年有n天,然后问你至少找多少个人,让其中有两个人在同一天生日的概率大于等于0.5;
其实要求所有人都不再同一天生日的概率小于等于0.5
其实就是A(n,x)/n^x <=0.5就行了
AC代码:http://paste.ubuntu.net/15157601/
lightoj 1151
这题是有100个位置,然后骰子可以掷出1-6,走1-6步,但是还有蛇和楼梯,所以这其实是一个有环的期望问题
e[i]=1+e[i+1]+e[i+2]+...+e[i+6];
如果i处有楼梯或者蛇,e[i]=e[go[i]];
构造好矩阵,直接套高斯消元的期望模版就行了
AC代码:http://paste.ubuntu.net/15157659/
lightoj 1248
这题是给你个n面的骰子,然后问你n面全部扔出来的次数的期望
dp[i]表示已经扔出来了i面的期望,他可以转移到dp[i]和dp[i+1]
dp[i]=i/n*dp[i]+(n-i)/n*dp[i+1]+1;
dp[i]=dp[i+1]+n/(n-i);
AC代码:http://paste.ubuntu.net/15157824/
lightoj 1265
给你一些老虎和鹿,然后还有你,两两碰到会发生一些事情,问你存活下来的概率
先找出你能存活的情况,然后dp一下
AC代码:http://paste.ubuntu.net/15157958/
lightoj 1274
给你一个长度s的字符串,然后告诉你yes和no加起来有n个,然后可以换出来yes的个数和no的个数,然后yes可以看成1,no看成0,然后问你对于所有排列,把这个排列右移一位然后左边添上yes之后和原来的串不一样的个数的期望的平均
讲道理这题我没怎么懂题意,其实就是求排列里面相邻不同的个数把,然后问你有a个1,b个0的时候,能出现的相邻不同的个数的期望,如果第一位是0的话,还要加1
dp[i][j][flag]表示前面i个有j个1,并且第i位是flag,然后就这么瞎搞吧,然后你取到1或者0的概率算一下,然后搞一下
最后输出dp[0][0][1],因为最前面要放个1,所以如果第一位是0的话还要+1,然后数组开不下,所以要用滚动数组
感觉这题表达的也不清楚,反正记住期望要倒着算,以后碰到题目还是要随机应变啊
AC代码:http://paste.ubuntu.net/15158239/
lightoj 1284
这题是给你个三维空间,起初都是off,然后你选两个点,两点之间的按钮都被打开(如果开着就关闭),然后问你k次操作后是on的个数的期望
这题其实要考虑每个位置被打开的概率(操作奇数次)
然后就是算这个一次操作里位置被选中的概率p,那么就是(1-x坐标没被选中的概率)*(1-y坐标没被选中的概率)*(1-z坐标没被选中的概率)
然后要算k次里被选中奇数次,记p[n]为n次里选中奇数次的概率,g[n]为n次里选中偶数次的概率
p[n]=1-g[n];
g[n]=p[n-1]*p+(1-p)*g[n-1]=p[n-1]*p+(1-p)*(1-p[n-1])=1+2*p*p[n-1]-p[n-1]-p;
p[n]=(1-2p)*p[n-1]+p;
p[n]-1/2=(1-2p)*(p[n-1]-1/2);
p[0]=0;
求出p[n],然后对每个位置ans+=p[n];
AC代码:http://paste.ubuntu.net/15158463/
poj 2151
给你几个队伍,然后每个队伍做对每题的概率,让你求每个队至少做出1题,并且至少一个队伍做出来n题的概率
先求出每个队伍都做不出题的概率,然后减一下,乘一下,得到至少1题的概率,dp求出每个队过不满n题的概率,然后乘起来每个队都过题但是不满n题的概率,然后上面个概率减去下面个就好了。
概率一定要想清楚,我开头没想清楚,就乘了然后wa
AC代码:http://paste.ubuntu.net/15243169/
codeforces 148D
这题是说有黑的b个白的w个,然后两个人开始抓老鼠,谁抓到白的就赢,然后龙每次抓,剩下的都会随即逃走一只,然后如果没有老鼠了,算龙赢,问你公主赢的概率
这题要找出公主的状态转移,而不能一会考虑公主一会考虑龙
dp[i][j]是剩下i个白,j个黑的时候公主赢的概率,于是可以转移到dp[i][j]=i/(i+j)+.....
后面是公主抓黑的,龙不能抓白的,所以也是黑的,然后随即跑一个是黑的或者白的,就这两个转移
AC代码:http://paste.ubuntu.net/15243211/
poj 3071
踢足球,然后给你每个队战胜其他队的概率,然后貌似是相邻的两两先进行比赛,然后问你谁最终胜出的概率最高
2的n次个球队,所以n轮就能有人最终胜出,所以只要算每轮,他赢得概率是多少,他需要战胜上一轮对面的每个对手
dp[j][i]+=dp[j][i-1]*dp[k][i-1]*p[j][k];
AC代码:http://paste.ubuntu.net/15243241/
题意:有三个骰子,分别有k1,k2,k3个面。
每次掷骰子,如果三个面分别为a,b,c则分数置0,否则加上三个骰子的分数之和。
当分数大于n时结束。求游戏的期望步数。初始分数为0
设dp[i]表示达到i分时到达目标状态的期望,pk为投掷k分的概率,p0为回到0的概率
则dp[i]=∑(pk*dp[i+k])+dp[0]*p0+1;
都和dp[0]有关系,而且dp[0]就是我们所求,为常数
设dp[i]=A[i]*dp[0]+B[i];
代入上述方程右边得到:
dp[i]=∑(pk*A[i+k]*dp[0]+pk*B[i+k])+dp[0]*p0+1
=(∑(pk*A[i+k])+p0)dp[0]+∑(pk*B[i+k])+1;
明显A[i]=(∑(pk*A[i+k])+p0)
B[i]=∑(pk*B[i+k])+1
先递推求得A[0]和B[0].
那么 dp[0]=B[0]/(1-A[0]);
dp求期望的题。
题意:
有n个房间,由n-1条隧道连通起来,实际上就形成了一棵树,
从结点1出发,开始走,在每个结点i都有3种可能:
1.被杀死,回到结点1处(概率为ki)
2.找到出口,走出迷宫 (概率为ei)
3.和该点相连有m条边,随机走一条
求:走出迷宫所要走的边数的期望值。
设 E[i]表示在结点i处,要走出迷宫所要走的边数的期望。E[1]即为所求。
叶子结点:
E[i] = ki*E[1] + ei*0 + (1-ki-ei)*(E[father[i]] + 1);
= ki*E[1] + (1-ki-ei)*E[father[i]] + (1-ki-ei);
非叶子结点:(m为与结点相连的边数)
E[i] = ki*E[1] + ei*0 + (1-ki-ei)/m*( E[father[i]]+1 + ∑( E[child[i]]+1 ) );
= ki*E[1] + (1-ki-ei)/m*E[father[i]] + (1-ki-ei)/m*∑(E[child[i]]) + (1-ki-ei);
设对每个结点:E[i] = Ai*E[1] + Bi*E[father[i]] + Ci;
对于非叶子结点i,设j为i的孩子结点,则
∑(E[child[i]]) = ∑E[j]
= ∑(Aj*E[1] + Bj*E[father[j]] + Cj)
= ∑(Aj*E[1] + Bj*E[i] + Cj)
带入上面的式子得
(1 - (1-ki-ei)/m*∑Bj)*E[i] = (ki+(1-ki-ei)/m*∑Aj)*E[1] + (1-ki-ei)/m*E[father[i]] + (1-ki-ei) + (1-ki-ei)/m*∑Cj;
由此可得
Ai = (ki+(1-ki-ei)/m*∑Aj) / (1 - (1-ki-ei)/m*∑Bj);
Bi = (1-ki-ei)/m / (1 - (1-ki-ei)/m*∑Bj);
Ci = ( (1-ki-ei)+(1-ki-ei)/m*∑Cj ) / (1 - (1-ki-ei)/m*∑Bj);
对于叶子结点
Ai = ki;
Bi = 1 - ki - ei;
Ci = 1 - ki - ei;
从叶子结点开始,直到算出 A1,B1,C1;
E[1] = A1*E[1] + B1*0 + C1;
所以
E[1] = C1 / (1 - A1);
若 A1趋近于1则无解...
else{
if(cnt<n) k--;
for(int i=0;i<cnt;i++){
if(k&(1LL<<i)) ans^=a[cnt-i];
}
printf("%I64d\n",ans);
}