[HDU 4576]Robot[概率DP]

来源:互联网 发布:马鞍山网络招聘网 编辑:程序博客网 时间:2024/05/19 21:59
题意:

环形cell, robot初始在1号,顺逆时针走概率各半.每次走w,问x次后停在l和r之间的概率.

思路:

正着推,方程很显然. 需要注意空间优化为2行, 时间上减少mod的次数.

#include <cstdio>#include <cstring>using namespace std;const int MAXM = 1e6+5;const int MAXN = 205;double dp[2][MAXN];int m,n,l,r,w;inline int mymod(int a, int mod)//[1,n]{    return ((a-1)%mod + mod)%mod + 1;}int main(){    while(scanf("%d %d %d %d",&n,&m,&l,&r) && (n+m+l+r))    {        memset(dp[0],0,sizeof(dp[0]));        dp[0][1] = 1;        for(int i=1;i<=m;i++)        {            scanf("%d",&w);            for(int j=1;j<=n;j++)            {                if(j-w>=1)                {                    if(j+w<=n)                        dp[i&1][j] = 0.5*dp[(i&1)^1][j-w] + 0.5*dp[(i&1)^1][j+w];                    else                        dp[i&1][j] = 0.5*dp[(i&1)^1][j-w] + 0.5*dp[(i&1)^1][mymod(j+w,n)];                }                else                {                    if(j+w<=n)                        dp[i&1][j] = 0.5*dp[(i&1)^1][mymod(j-w,n)] + 0.5*dp[(i&1)^1][j+w];                    else                        dp[i&1][j] = 0.5*dp[(i&1)^1][mymod(j-w,n)] + 0.5*dp[(i&1)^1][mymod(j+w,n)];                }            }        }        double ans = 0;        for(int i=l;i<=r;i++)            ans += dp[m&1][i];        printf("%.4lf\n",ans);    }}