HDU4405 Areoplane chess(期望dp)

Areoplane chess

傳送門1
傳送門2
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(1N100000) and M(0M1000).
Then M lines follow, each line contains two integers Xi,Yi(1Xi<YiN).
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+1 個點(編號0N ),一個人玩遊戲,從0 出發,當到達N 或大於N 的點則遊戲結束。每次行動擲骰子一次,骰子編號16 ,擲到多少就向前走幾步,這個數軸上還有些特殊點,可以從XiYi 。求總共投擲骰子次數的期望。

分析

期望dp.(期望dp一般逆推)
定義dp[i] 表示在i 時距離遊戲結束還要投擲骰子次數的期望。
1. 對於可以直接飛的點,dp[i]=dp[fly[i]].
2. 不能飛的點,

dp[i]=6j=1dp[i+j]6+1

dp[i]=dp[i+1]+dp[i+2]+dp[i+3]+...+dp[i+6]6+1

CODE

#include<cstdio>
#include<memory.h>
#define N 100005
#define FOR(i,a,b)  for(int i=(a),i##_END_=(b);i<=i##_END_;i++)
#define ROF(i,a,b)  for(int i=(a),i##_END_=(b);i>=i##_END_;i--)
double dp[N];
int fly[N];

int main() {
    int n,m;
    while(~scanf("%d%d",&n,&m)&&(n||m)) {
        memset(fly,-1,sizeof fly);
        FOR(i,1,m) {
            int a,b;
            scanf("%d%d",&a,&b);
            fly[a]=b;
        }
        memset(dp,0,sizeof dp);
        ROF(i,n-1,0) {
            if(fly[i]==-1) {
                FOR(j,i+1,i+6)dp[i]+=dp[j]/6.0;
                dp[i]++;
            } else dp[i]=dp[fly[i]];
        }
        printf("%.4lf\n",dp[0]);
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章