hdu4405 概率dp

飞行棋,从0到n,置骰子,置到几就往前走几步,前进中会有捷径,比如2和5连到一起了,那你走到2时可以直接跳到

5,如果5和8连到一起了,那你还可以继续跳到8,最后问跳到n时平均置几次骰子。也就是求期望。


非常好的入门资料 : 点击打开链接


比如n=3,m=0
所列方程为e[0]=1/6e[1]+1/6e[2]+1/6e[3]+1
                  e[1]=1/6e[2]+1/6e[3]+1
                  e[2]=1/6e[3]+1
                  e[3]=0
从0这个点可以到1,2,3,4,5,6这几个位置,由于大于等于3游戏结束,不会再有期望的投色子次数了,所以跳到3和大于3的格子里期望值也就都是0了。
所以我们列出n个方程后直接回带就能把e[0]求出来。如e[3]=0可以求出e[2]=1,已知了e[2]和e[3]就可以求出e[1],进而求出e[0].
两层for循环就是一个回带的过程。
题目还有可以直接从a跳到b,不需要投色子的,那样就直接标记一下,a的期望值也就等于b的期望值。(a<b)

const  int maxn = 100008 ;
int  to[maxn] ;
double dp[maxn] ;

int  main(){
     int i , j , n  , m , u , v ;
     while(cin>>n>>m){
           if(n==0 && m==0) break ;
           memset(to , -1 , sizeof(to)) ;
           while(m--){
                scanf("%d%d" , &u ,&v) ;
                to[u] = v ;
           }
           memset(dp , 0 , sizeof(dp)) ;
           for(i = n-1 ; i >= 0 ; i--){
                if(to[i] != -1) dp[i] = dp[to[i]] ;
                else{
                    for(j = 1 ; j <= 6 ; j++)  dp[i] += dp[i+j] ;
                    dp[i] = dp[i] / 6.0 + 1.0 ;
                }
           }
           printf("%.4lf\n" , dp[0]) ;
     }
     return 0 ;
}


你可能感兴趣的:(hdu4405 概率dp)