hdu 4405结题报告——常规的数学期望

Aeroplane chess

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

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,1,2,............,N这些数,其中有M条飞行线从a到b,某一点从0开始出发然后扔一个6面骰子,扔到几就走几步;如果走完这一步时这个点在某一飞行线的起始点,那么这个点就可以沿飞行线走到飞行线的终点,点可以沿飞行线可以连续移动。求所扔骰子的次数的期望使得这个点可以到达这排格子的终点(格子的终点的定义是这个点到达标有数N的格子或超过这个格子)

开始我以为是一个马氏链之类的东西,想用转移矩阵的快速幂来解决,但后来发现100000的数据量矩阵根本存不下来。后来用递推的方法算是勉勉强强的写出来了,还堆栈溢出了一次,后来发现是没把数组搞成全局变量的问题。

具体思路就是设ans[i]是点在格子i到格子N所求的期望,然后a[i]就等于a[i+j]/6(j=1,2,.......,6)之和再+1;如果格子i有飞行线到k,那么a[i]=a[k](因为题目保证格子i出没有两条以上的飞行线,所以这样是可行的),最终结果为a[0]

程序

#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<string.h>
#define MAXN 100005
using namespace std;
int fly[MAXN];
double ans[MAXN];
int main()
{
    int N,M;
    int i,j,k;
    while(scanf("%d%d",&N,&M)!=EOF&&(N+M))
    {
        int a,b;
        memset(fly,0,sizeof(fly));
        memset(ans,0,sizeof(ans));
        for(i=0;i<M;i++)
        {
            scanf("%d%d",&a,&b);
            fly[a]=b;
        }
        for(i=N-1;i>=0;i--)
        {
            if(fly[i]!=0)
            {
                ans[i]=ans[fly[i]];
            }
            else
            {
                for(j=1;j<=6;j++)
                {
                    if(i+j<N)
                    {
                        ans[i]+=(ans[i+j]*(1.0/6.0));
                    }
                    else
                    {
                        ans[i]+=(ans[N]*(1.0/6.0));
                    }
                }
                ans[i]++;
            }
        }
        printf("%.4lf\n",ans[0]);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值