现在的位置: 首页 > 综合 > 正文

hdu 4405 Aeroplane chess 2012年金华区域赛网络赛 概率dp求期望

2019年09月03日 ⁄ 综合 ⁄ 共 2379字 ⁄ 字号 评论关闭

Aeroplane chess

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

Total Submission(s): 1155    Accepted Submission(s): 785



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
 


Source
 


Recommend
zhoujiaqi2010   |   We have carefully selected several similar problems for you:  4834 4833 4832 4831 4830 
 

题意:有1个1*(n+1)的格,下标为0~n ;起始于0格,每步掷一次骰子,掷到i,前进i步,某些格子可以直达别的格子无需掷骰子,问到达>=n位置所需掷骰子次数的期望。

思路:总期望为子期望的加权和,加权因子为状态转移概率。设dp[ i ]为从i开始到达目标状态的期望,dp[ i ]有6种转移方式:

(1)dp[ i ] ------>dp[ i + 1 ] , 转移概率为1/6;

(2)dp[ i ] ------>dp[ i + 2 ] , 转移概率为1/6;

(3)dp[ i ] ------>dp[ i + 3 ] , 转移概率为1/6;

(4)dp[ i ] ------>dp[ i + 4 ] , 转移概率为1/6;

(5)dp[ i ] ------>dp[ i + 5 ] , 转移概率为1/6;

(6)dp[ i ] ------>dp[ i + 6 ] , 转移概率为1/6;

所以dp[ i ] =1 / 6 * ( ( dp[ i + 1 ] + 1 ) + ( dp[ i + 2 ] + 1 ) + ( dp[ i + 3 ] + 1 ) + ( dp[ i + 4 ] + 1 ) + ( dp[ i + 5 ] + 1 ) + ( dp[ i + 6 ] + 1 ) ) ,

化简得:dp[ i ] =1 + 1 / 6 * ( ( dp[ i + 1 ] ) + ( dp[ i + 2 ] ) + ( dp[ i + 3 ] ) + ( dp[ i + 4 ] ) + ( dp[ i + 5 ] ) + ( dp[ i + 6 ] ) ); 

不过注意:转移的前提是没有直达的情况,所以之间需要判是否存在直达,若存在直接赋值。详见代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=100000+100;
int n,m;
double dp[MAXN];
int vis[MAXN];
int main()
{
   // freopen("text.txt","r",stdin);
    while(~scanf("%d%d",&n,&m) && n+m)
    {
        memset(vis,0,sizeof(vis));
        for(int i=0;i<m;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            vis[x]=y;
        }
        memset(dp,0,sizeof(dp));
        for(int i=n-1;i>=0;i--)
        {
            if(vis[i])
            {
                 dp[i]=dp[vis[i]];
                 continue;
            }
            dp[i]=1.0+1.0/6.0*(dp[i+1]+dp[i+2]+dp[i+3]+dp[i+4]+dp[i+5]+dp[i+6]);
        }
        printf("%.4f\n",dp[0]);
    }
    return 0;
}

抱歉!评论已关闭.