bc第七场Little Pony and Dice(dp)

来源:互联网 发布:8848网络用语什么意思 编辑:程序博客网 时间:2024/05/22 01:43

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

题意:给定一个n和m,m表示可以掷出从1——m,且都是等概率的,类似于玩飞行棋,问恰好走到n点的概率

思路:

dp[i]: 恰好走到i点的概率

dp[i]=dp[i-1]*(1/m)+(dp[i-1]-dp[i-m-1]*(1.0/m))

dp[i-1]*(1/m)代表从i-1这个点走到i点的概率。

(dp[i-1]-dp[i-m-1]*(1.0/m))所有走到i-1的点除了i-m-1点外,其他的点都能走到i,并且走到i-1和走到i的概率相同

如果相邻的两个i之间的dp[i]相差很小,那说明下一个dp[i]的变化也会很小。以后就都是这个定值了。所以直接输出就好

 我最初的思路是,递归:dp[i]=(dp[i-1]+dp[i-2]+……+dp[i-m])/m,循环一遍,从i-1,一直到i-1-m,然后把所有的dp加起来,再除以m,但是这样t了,姿势还是不够优美、、

代码:

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#define ll long long
#define maxn 1000005
#define eps 1e-13
using namespace std;
double a[maxn];
int f(int n,int m)
{
    memset(a,0.0,sizeof(a));
    a[0]=1.0;
    a[1]=1.0/m;
    for(int i=2;i<=n;i++)
    {
         
        //for(int j=i-1;j>=0&&j>=i-m;j--) a[i]+=a[j]/m;
            a[i]+=a[i-1]/m+a[i-1];
         if(i-m-1>=0)
            a[i]-=a[i-1-m]/m;
        //printf("%.5lf ",a[i]);
     if(fabs(a[i]-a[i-1])<eps)
            return i;
    }
    return n;

}
int main()
{
    int m,n;
    while(scanf("%d%d",&m,&n)!=EOF)
    {
        int k=f(n,m);
        //cout<<k<<endl;
       if(n>k)
        printf("%.5lf\n",a[k]);
       else
        printf("%.5lf\n",a[n]);
    }
    return 0;
}

注意:如果把  if(fabs(a[i]-a[i-1])<eps)  return i;放在前面会re,具体原因也不知道,,这两天做题遇到瓶颈,不管多水的题,都能wa几发,或者re几发,,很是郁闷、、、伐开心

0 0