题意:在一个圈上,起点是1,有m次移动,每次顺时针移动wi格或者逆时针移动wi格,顺时针和逆时针的概率都是1/2。问最后停留在l到r之间的概率
思路:显然的递推式子:p[i][j]=0.5*p[i-1]([j+w)%n]+0.5*p[i-1][(j-w+n)%n];。本人用了输入优化。
虽然很暴力,但还是勉强ac了。(网上某些题解用G++能过,C++不能过),然后据说还有矩阵乘法的方法可以更快。
还有,特别奇怪的是,如果把p[now][j]=0.5*p[pre][(j-w+n)%n]+0.5*p[pre][(j+w)%n]换成p[now][j]=0.5*(p[pre][(j-w+n)%n]+p[pre][(j+w)%n])就会TLE,求大神解答。。。
#include<cstdio>
#include<cstring>
#include<cctype>
#define MAXN 205
float p[2][MAXN];
inline int readint()
{
char c=getchar();
while(!isdigit(c)) c=getchar();
int x=0;
while(isdigit(c))
{
x=x*10+c-'0';
c=getchar();
}
return x;
}
int main()
{
int n,m,l,r;
while(~scanf("%d%d%d%d",&n,&m,&l,&r))
{
if(!n && !m && !l && !r) break;
int now=0,w,pre=1;
memset(p[0],0,sizeof(p[0]));
p[0][0]=1.0;
while(m--)
{
w=readint();
now^=1,pre^=1;
for(int j=0;j<n;++j) p[now][j]=0.5*p[pre][(j-w+n)%n]+0.5*p[pre][(j+w)%n];
}
double ans=0.0;
for(int i=l-1;i<r;++i) ans+=p[now][i];
printf("%.4f\n",ans);
}
return 0;
}