hdu4576(概率DP)

题意:一个圆盘,有N个编号(1,2,3……N),从1号出发,每次能逆时针或顺时针向前走w步,问经过m次后,最终停留在区间【l,r】的概率。

思路:只要先求出经过m次后,最终在每个点的概率,然后把区间里的概率全部加起来即可。dp[i][j]表示第j次后停留在i的概率,那么这个状态显然是由两个状态递推过来的。dp[i][j]=dp[(i+w+n)%n][j-1]*0.5+dp[(i-w+n)%n][j-1]*0.5,发现每次转移只是第j和第j-1之间的转移所以第二维可以开滚动数组dp[i][temp]=0.5*dp[(i+w+n)%n][temp^1]+0.5*dp[(i-w+n)%n][temp^1];最后的ans直接就是:for(int i=l-1;i<=r-1;i++) ans+=dp[i][temp];具体代码如下:

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <cstring>
double dp[205][2];
int main()
{
    int n,m,l,r;
    while(scanf("%d%d%d%d",&n,&m,&l,&r)!=EOF)
    {
        if(n+m+l+r==0)break;
        memset(dp,0,sizeof(dp));
        dp[0][0]=1;
        int temp=0;
        while(m--){
            int w;
            scanf("%d",&w);
            temp^=1;
            for(int i=0;i<n;i++){
                dp[i][temp]=0.5*dp[(i+w+n)%n][temp^1]+0.5*dp[(i-w+n)%n][temp^1];
            }
        }
        double ans=0;
        for(int i=l-1;i<=r-1;i++){
            ans+=dp[i][temp];
        }
        printf("%.4lf\n",ans);
    };
    return 0;
}


主要体会一下求概率DP和求期望DP的区别,发现概率一般是正推过来的,而期望一般是逆推的。(比如本题和2013山东省赛那道期望DP)

posted @ 2014-05-12 15:45  Kevin_CongTang  阅读(235)  评论(0编辑  收藏  举报