HDU 4405 期望DP

来源:互联网 发布:淘宝ifashion手机进入 编辑:程序博客网 时间:2024/05/15 08:54

期望DP算是第一题吧...虽然巨水但把思路理理清楚总是好的。。

题意:在一个1×n的格子上掷色子,从0点出发,掷了多少前进几步,同时有些格点直接相连,即若a,b相连,当落到a点时直接飞向b点。求走到n或超出n期望掷色子次数


SOL:

    期望DP还是显然的,从后往前推也是显然的——这个题目能比较好地理解为什么要从后往前推。概率DP每个状态都在当前已知的概率下推出——最基本事件的概率往往都是已知的,而期望不同,从头开始,头的期望步数是根本不可知的,一旦遇上不可行状态极难处理,而从后往前推,最后一个状态的期望一般均为0,而它是由在它之前的状态转移而来,那么前面状态就可以更新了——

    ——例如本题,E[i]表示从第i个格子到第n个格子的期望步数,那么dp[n]显然等于0,而对于第i个点,它下一步可能的方向是i+1~6,那么根据概率的那什么公式累加已推出的点乘上概率——因为转移是要掷色子的所以还要再加上一。

   然而对于直接相连的两个点怎么考虑呢,对于相对位置靠前的那个点——它只能到下一个点,那么它的期望直接就传过来了。。连加一都不需要...所以期望&概率题需要考虑清楚状态之间的关系——保证DP的正确。


code:

#include <stdio.h>#include <string.h>#include <algorithm>#include <cstring>#define ll long longdouble dp[100005];int vis[100005];int main(){    int n,m;    while(scanf("%d%d",&n,&m)!=EOF){        if((n+m)==0)break;        memset(vis,-1,sizeof(vis));        for(int i=1;i<=m;i++){            int a,b;            scanf("%d%d",&a,&b);            vis[a]=b;        }        memset(dp,0,sizeof(dp));        for(int i=n-1;i>=0;i--){            if(vis[i]==-1){                for(int j=1;j<=6;j++){                    dp[i]+=dp[i+j]/6.0;                }                dp[i]+=1;            }            else                 dp[i]=dp[vis[i]];        }        printf("%.4lf\n",dp[0]);    }    return 0;}


0 0
原创粉丝点击