Aeroplane chess(期望dp)

版权声明:本文为博主原创文章,转载请说明出处。 https://blog.csdn.net/xianpingping/article/details/83245094

Aeroplane chess

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 6260    Accepted Submission(s): 3893


 

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

题意:就是飞行棋,求到达n的期望步数。如果3 5,就是到了3节点不用掷筛子直接就能到5.否则的话要掷筛子

思路:

期望DP还是显然的,从后往前推也是显然的——这个题目能比较好地理解为什么要从后往前推。概率DP每个状态都在当前已知的概率下推出——最基本事件的概率往往都是已知的,而期望不同,从头开始,头的期望步数是根本不可知的,一旦遇上不可行状态极难处理,而从后往前推,最后一个状态的期望一般均为0,而它是由在它之前的状态转移而来,那么前面状态就可以更新了——

    ——例如本题,E[i]表示从第i个格子到第n个格子的期望步数,那么dp[n]显然等于0,而对于第i个点,它下一步可能的方向是i+1~6,那么根据概率的那什么公式累加已推出的点乘上概率——因为转移是要掷色子的所以还要再加上一。

   然而对于直接相连的两个点怎么考虑呢,对于相对位置靠前的那个点——它只能到下一个点,那么它的期望直接就传过来了。。连加一都不需要...所以期望&概率题需要考虑清楚状态之间的关系——保证DP的正确。

代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn=100000+100;
int lala[maxn];
double dp[maxn];
int main()
{
    int n,m,a,b;
    while(scanf("%d%d",&n,&m)!=EOF){
        if(n==0 && m==0)
        break;
        memset(lala,0,sizeof(lala));
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=m;i++){
            scanf("%d%d",&a,&b);
            lala[a]=b;///b能由a到达。b大,a小
        }
        dp[n]=0;
        for(int i=n-1;i>=0;i--){
            if(lala[i]){
                dp[i]=dp[lala[i]];///i可以由lala[i]到达
            }
            else{
               /// if()
                dp[i]=(dp[i+1]+dp[i+2]+dp[i+3]+dp[i+4]+dp[i+5]+dp[i+6])*1.0/6+1;
            }
        }
        printf("%.4f\n",dp[0]);
       /// cout<<dp[0]<<endl;
    }
}

猜你喜欢

转载自blog.csdn.net/xianpingping/article/details/83245094