HDU 4576 Robot(概率dp)

题目

 

/*********************复制来的大致题意**********************

 

 有N个数字,M个操作, 区间L, R。 然后问经过M个操作后落在[L, R]的概率。

*******************************************************/

//自己做,错掉了,然后参考了别人的解法,说是要 概率dp

//概率模拟题,一定要用概率来模拟,

//因为数据很大,可能超了__int64,

//模拟方式用dp[2][], 0表示前一个状态,1表示现在的状态,

 

 

 

//WA掉的解法:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;

int main()
{
    int n,m,l,r,w,i,j;
    __int64 a[210],a1[210];
    int temp1,temp2,temp;
    __int64 fenzi,fenmu;

    while(scanf("%d%d%d%d",&n,&m,&l,&r)!=EOF)
    {
        if(n==0&&m==0&&l==0&&r==0)break;
        memset(a,0,sizeof(a));
        memset(a1,0,sizeof(a1));
        a[1]=1;
        a1[1]=1;

        for(i=0;i<m;i++)
        {
            scanf("%d",&w);
            w=w%n;
            for(j=1;j<=n;j++)
            {
                if(a[j]!=0)
                {
                    temp=a[j];
                    temp1=j+w;
                    while(temp1>n)temp1=temp1-n;
                    temp2=j-w;
                    while(temp2<1)temp2=temp2+n;
                    a1[temp1]+=a[j];
                    a1[temp2]+=a[j];
                    a1[j]=a1[j]-temp;
                }
            }
            for(j=1;j<=n;j++)
            {
                a[j]=a1[j];
            }
        }

        fenzi=0;
        fenmu=0;
        for(j=1;j<=n;j++)
        {
            fenmu=fenmu+a[j];
        }
        for(j=l;j<=r;j++)
        {
            fenzi=fenzi+a[j];
        }

        printf("%.4lf\n",(fenzi*1.0)/(fenmu*1.0));

    }
    return 0;
}
View Code

//我猜测搓掉的原因是数据太大,导致越界,然后结果就不准了,因为m很大哦~

 

 

 

//可以AC的解法:

//听说这种解法叫做简单的概率dp
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std; 
int main()
{
    int n,m,l,r,w,i,j;
    int temp1,temp2,temp;
    double dp[2][210]; //0 1 表示前后两次,210 表示点 dp 概率

    while(scanf("%d%d%d%d",&n,&m,&l,&r)!=EOF)
    {
        if(n==0&&m==0&&l==0&&r==0)break;
        memset(dp,0,sizeof(dp));
        dp[0][1]=1;
        temp = 0; //状态 0 1
        for(i=1;i<=m;i++)
        {
            scanf("%d",&w);
            for(j=1;j<=n;j++)
            {
                temp1=j+w;
                while(temp1>n)temp1=temp1-n;
                temp2=j-w;
                while(temp2<1)temp2=temp2+n;
                dp[(temp+1)%2][temp1]+=dp[temp][j]*0.5;
                dp[(temp+1)%2][temp2]+=dp[temp][j]*0.5;
                dp[temp][j]=0;   
            }
            temp=(temp+1)%2;
        }
        double ans = 0.0;
        for(i=l;i<=r;i++)
        {
            ans+=dp[temp][i];
        }
        printf("%.4lf\n",ans);
    }
    return 0;
}
View Code

 

posted @ 2014-06-22 23:21  laiba2004  Views(174)  Comments(0Edit  收藏  举报