• 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
    ",(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
    ",ans);
        }
        return 0;
    }
    View Code
    一道又一道,好高兴!
  • 相关阅读:
    蓝桥杯_基础_杨辉三角
    蓝桥杯_基础_数组特征
    蓝桥杯_基础_美丽的图形
    脉象
    词根汇总
    蓝桥杯 入门训练 Fibonacci数列 解析
    制作tomcat重启.bat文件
    day23(023-递归练习)
    day27(027-反射&JDK新特性)
    day25(025-多线程(下)&GUI)
  • 原文地址:https://www.cnblogs.com/laiba2004/p/3803242.html
Copyright © 2020-2023  润新知