您的位置:首页 > 其它

期望dp

2017-07-04 21:12 92 查看
实在不好意思说自己做过几道期望dp的水题(水题都好难啊,反正我刚才去看是不会的)

弱弱地跑回去看了学长的PPT。

各种乱七八糟的公式整理一发:

概率

贝叶斯公式:P(B|A)=P(B)*P(A|B)/P(A)

翻译:如果事件A发生,事件B发生的概率为事件B发生的概率*如果事件B发生则事件A发生的概率/事件A发生的概率

用这个可以证明:P(B)*P(A|B)=P(AB)=P(A)*P(B|A)

(这个常用来P(B|A)和P(A|B)的相互转化)

期望

期望是试验中每次可能结果的概率乘以其结果的总和。

对于随机变量X,它的期望E(X)=sigma{基本结果i发生的概率*发生基本结果i时X的数值,i是一个基本结果}

也可以把X取值相同的基本结果合并成一个事件考虑

E(X)=sigma{i*X取值为i的概率,i是一个可能的取值}

举几个例子来理解期望:

1。在17世纪,有一个赌徒向法国著名数学家帕斯卡挑战,给他出了一道题目:甲乙两个人赌博,他们两人获胜的机率相等,比赛规则是先胜三局者为赢家,赢家可以获得100法郎的奖励。当比赛进行到第四局的时候,甲胜了两局,乙胜了一局,这时由于某些原因中止了比赛,那么如何分配这100法郎才比较公平?用概率论的知识,不难得知,甲获胜的可能性是,甲赢了第四局,或输掉了第四局却赢了第五局,概率为1/2+(1/2)(1/2)=3/4。分析乙获胜的可能性,乙赢了第四局和第五局,概率为(1/2)(1/2)=1/4。因此由此引出了甲的期望所得值为100*3/4=75法郎,乙的期望所得值为25法郎。这个故事里出现了“期望”这个词,数学期望由此而来。

2。关于掷骰子这件事。

它的期望值=1*(1/6)+2*(1/6)+3*(1/6)+4*(1/6)+5*(1/6)+6*(1/6)=3.5

期望的线性性(可加性)

P(X+Y) = P(X)+P(Y)

例题:

hdu4405

Aeroplane chess

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 4144 Accepted Submission(s): 2634

Problem Description

Hzz loves aeroplane chess very much. The chess map contains N+1 grids labeled from 0 to N. Hzz starts at grid 0. For each step he throws a dice(a dice have six faces with equal probability to face up and the numbers on the faces are 1,2,3,4,5,6). When Hzz is at grid i and the dice number is x, he will moves to grid i+x. Hzz finishes the game when i+x is equal to or greater than N.

There are also M flight lines on the chess map. The i-th flight line can help Hzz fly from grid Xi to Yi (0 < Xi < Yi<=N) without throwing the dice. If there is another flight line from Yi, Hzz can take the flight line continuously. It is granted that there is no two or more flight lines start from the same grid.

Please help Hzz calculate the expected dice throwing times to finish the game.

Input

There are multiple test cases.

Each test case contains several lines.

The first line contains two integers N(1≤N≤100000) and M(0≤M≤1000).

Then M lines follow, each line contains two integers Xi,Yi(1 ≤ Xi < Yi≤N).

The input end with N=0, M=0.

Output

For each test case in the input, you should output a line indicating the expected dice throwing times. Output should be rounded to 4 digits after decimal point.

Sample Input

2 0

8 3

2 4

4 5

7 8

0 0

Sample Output

1.1667

2.3441

题目大意:飞行棋,从0开始走,置骰子,置到几就往前走几步,到达大于等于n的地方就结束,前进中会有捷径,比如2和5连到一起了,那你走到2时可以直接跳到5,如果5和8连到一起了,那你还可以继续跳到8,问期望置几次骰子可以结束游戏。

这道题以前做过,都不知道怎么过的,没有写题解,所以现在写吧。有机会以前做的几道题都可以重新做一下2333对自己以前的学习态度F2。

设dp数组,dp[i]表示到i位置时距离结束游戏还期望的值

显然dp
=0,而最后的结果就在dp[1]里

(期望dp的经典套路,一开始做很茫然,后来多做几道就…)

1:考虑没有捷径的点i

它下一步有可能去到i+1,i+2,i+3…i+6,那么它的还期望的值就会等于dp[i+1]*P(到达i+1)//其实P(到达i+1) 就是1/6

+dp[i+2]*P(到达i+2)

+…

+dp[i+6]*P(到达i+6)

而到达这个点还期望再掷一次骰子到达接下来的6个状态,所以dp[i]+=1;

2.对于那些有捷径的点

eg:已给出条件:a可以直接跳到b

只要到达a可以直接到达b,那么到达a还剩的期望数就完全等于到b还剩的期望数。

所以dp[a]=dp[b]

代码(这个是之前写的)

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

const int N = 100000+10;

int n,m;
double f
;
int a
,b
;
double ans=0;

int main(){
//   printf("2");
while(scanf("%d%d",&n,&m)!=EOF){
if(n+m==0) break;
memset(a,-1,sizeof(a));
memset(b,-1,sizeof(b));
memset(f,0,sizeof(f));
while(m--){
int i,x;
scanf("%d%d",&i,&x);
//      if(i>x) b[i]=x;
//      else a[x]=i;
a[i]=x;
}
f
=0;
for(int i=n;i>=0;i--){
if(a[i]!=-1) {f[i]+=f[a[i]];continue;}//这个地方我纠结了好久,为什么一定可以保证更新f[i]的时候f[a[i]]一定更新了
//然后跑回去读了原题  0<Xi<Yi<=N 气死我了。。。
if(i==n) continue;
f[i]+=1;
for(int j=1;j<=6;j++){
f[i]+=(double)1.0*f[i+j]/6;
}
}
/*for(int i=n;i>=0;i--){
if(a[i]!=-1) {f[i]+=f[a[i]];continue;}
if(b[i]!=-1) {f[b[i]]+=f[i];continue}
if(i==n) continue;
f[i]+=1;
for(int j=i-1;j>=i-6;j--){
f[j]+=(double)1.0*f[i]/6;
}
}*///这样写有一个bug 当b[i]的值更新后,那b[i+j] 1<=j<=6也应该更新 所以无法满足无后效性
printf("%0.4lf\n",f[0]);}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: