分析:给出1~n的环,m个操作,每次能顺时针或逆时针走w步(每次从某一个数字到达另外数字的概率为0.5),询问最后在l~r这段区间内概率。
按概率dp求出到达每个数字的概率,然后枚举从l到r的概率相加即可。dp[i][j]表示第i次操作落在数字j上的概率。
每次只需要需要取上一次的数据 ,只要开2个缓冲即可。
这题卡时限卡的非常紧,代码稍挫一点就TLE了。
#include<iostream>
using namespace std;
double dpa[220],dpb[220]; //概率DP,dp[i][j]表示第i步走到点j的概率
int main()
{
int n,m,l,r,w,i;
double ans;
while(scanf("%d%d%d%d",&n,&m,&l,&r)==4 && n+m+l+r)
{
memset(dpa,0,sizeof(dpa));
memset(dpb,0,sizeof(dpb));
dpa[0]=1.0;
while(m--)
{
scanf("%d",&w);
for(i=0;i<n;i++)
if(dpa[i]>0)
{
dpb[(i+w)%n]+=dpa[i]*0.5;
dpb[(i-w+n)%n]+=dpa[i]*0.5;
}
for(i=0;i<n;i++)
{
dpa[i]=dpb[i];
dpb[i]=0;
}
}
ans=0;
for(i=l-1;i<r;i++)
ans+=dpa[i];
printf("%.4lf\n",ans);
}
return 0;
}
原文地址:http://blog.csdn.net/a809146548/article/details/46412711