2 0 8 3 2 4 4 5 7 8 0 0
1.1667 2.3441
从0点走到n点。每一次掷筛子得x,向前走x步,有m条飞行通道,能够不算向前走,直接飞到。没有两个飞行线路从同一个点出发,问期望。
dp[i] = ∑(1/6*dp[i+j])+1 ;
对于飞行路线,由i到j的飞行路线,那么就意味着,当它到第i个位置的时候。他就到了第j个位置。dp[i] == dp[j]
从后先前dp,对于每个以计算的dp。有没有飞行路线能够到达这个点,假设有那么那个点的dp也就计算出了
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
struct node{
    int u , v ;
    int next ;
}p[2000];
int head[100000] , cnt ;
double dp[110000] , k[7];
void add(int u,int v)
{
    p[cnt].u = u ;
    p[cnt].v = v ;
    p[cnt].next = head[v] ;
    head[v] = cnt++ ;
}
int main()
{
    int n , m , i , j , l , u , v ;
    for(i = 1 ; i <= 6 ; i++)
        k[i] = 1.0/6 ;
    while(scanf("%d %d", &n, &m) && n+m != 0)
    {
        memset(head,-1,sizeof(head));
        for(i = 0 ; i < n ; i++)
            dp[i] = -1;
        cnt = 0 ;
        while(m--)
        {
            scanf("%d %d", &u, &v);
            add(u,v);
        }
        for(i = n ; i <= n+6 ; i++)
            dp[i] = 0 ;
        for(l = head[n] ; l != -1 ; l = p[l].next)
            dp[ p[l].u ] = dp[n] ;
        for(i = n-1 ; i >= 0 ; i--)
        {
            if( dp[i] != -1 )
            {
                for(l = head[i] ; l != -1 ; l = p[l].next)
                    dp[ p[l].u ] = dp[i] ;
                continue ;
            }
            dp[i] = 1 ;
            for(j = 1 ; j <= 6 ; j++)
                dp[i] += k[j]*dp[i+j] ;
            for(l = head[i] ; l != -1 ; l = p[l].next)
                dp[ p[l].u ] = dp[i] ;
        }
        printf("%.4lf\n", dp[0]);
    }
    return 0;
}
 
hdu4405--Aeroplane chess(概率dp第七弹:飞行棋游戏--2012年网络赛)
原文:http://www.cnblogs.com/brucemengbm/p/7065341.html