分析:给出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