zoukankan      html  css  js  c++  java
  • hdu 4576 (简单dp+滚动数组)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4576

    题意:给出1~n的环,m个操作,每次能顺时针或逆时针走w步,询问最后在l~r这段区间内概率。
    (1<=n<=200) ,(0<=m<=1,000,000),(1<=l<=r<=n).
    分析:每次从某一个数字到达另外数字的概率为0.5,按概率dp求出到达每个数字的概率,然后枚举从l到r的概率相加即可。
    dp[i][j]表示第i次操作落在数字j上的概率,但是不能直接开1000000*200的数组来保存中间结果,这肯定是会爆掉的。
    因为每次只需要取上一次的数据,所以可以用滚动数组,开dp[2][200]就行了
    注意:w可能比n大,所以要先w%n
    这一题卡时限卡的非常紧,代码稍微写挫一点就会超时了。
    代码如下:

     1 #include<stdio.h>
     2 #include<string.h>
     3 double dp[2][210];
     4 int main()
     5 {
     6     int n,m,l,r,i,t,k,w;
     7     while(scanf("%d%d%d%d",&n,&m,&l,&r)!=EOF)
     8     {
     9         if(n==0&&m==0&&l==0&&r==0)
    10             break;
    11         memset(dp,0,sizeof(dp));
    12         dp[0][0]=1;
    13         t=0;
    14         while(m--)
    15         {
    16             scanf("%d",&w);
    17             w%=n;
    18             k=t^1;
    19             for(i=0;i<n;i++)
    20                 dp[k][i]=0;
    21             for(i=0;i<n;i++)
    22             {
    23                 if(!dp[t][i])   //时限卡的很紧,加这一句来优化,减少运算次数
    24                     continue;
    25                 dp[k][(i+w)%n]+=0.5*dp[t][i];
    26                 dp[k][(i-w+n)%n]+=0.5*dp[t][i];
    27             }
    28             t=k;
    29         }
    30         double ans=0;
    31         for(i=l;i<=r;i++)
    32             ans+=dp[t][i-1];
    33         printf("%.4lf
    ",ans);
    34     }
    35     return 0;
    36 }
    View Code
  • 相关阅读:
    中心极限定理
    BCEloss和交叉熵损失的区别
    postgresql的python接口
    DataGrip 2020.1 安装与激活方法
    区块链技术
    TensorRT推理加速推断并提高吞吐量
    纯视觉取代slam做路径规划及避障的思路
    DL重新回顾总结
    OpenCV 轮廓方向
    OpenCV 低通滤波(可设置频率)
  • 原文地址:https://www.cnblogs.com/frog112111/p/3257322.html
Copyright © 2011-2022 走看看