题目链接 http://acm.split.hdu.edu.cn/showproblem.php?pid=4576
每次记录走这一步时每个格子的概率,下一次直接乘就行。
代码如下:
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
using namespace std;
double dp[2][250];
int main(){
#ifndef ONLINE_JUDGE
freopen("data.txt","r",stdin);
#endif
int n,m,l,r;
while(scanf("%d%d%d%d",&n,&m,&l,&r)&&(n||m||l||r)){
// memset(dp,0,sizeof(dp));
for(int i=0;i<249;++i){
dp[1][i]=0;
dp[0][i]=0;
}
int now=1,pre=0;
dp[0][1]=1;
for(int t=0;t<m;++t){
int w;
scanf("%d",&w);
w%=n;
for(int i=1;i<=n;++i){
if(dp[pre][i]!=0){
int add=((i+w)>n)?((i+w)-n):(i+w);
int mn=(i-w)<1?(n+(i-w)):(i-w);
if(add<1||add>n||mn<1||mn>n)cout<<dp[3][100000000]<<endl;
// cout<<mn<<' '<<add<<endl;
dp[now][mn]+=dp[pre][i]*0.5;
dp[now][add]+=dp[pre][i]*0.5;
}
}
// memset(dp[pre],0,sizeof(dp[pre]));
for(int i=0;i<249;++i){dp[pre][i]=0;}
now=now?0:1;
pre=1-now;
}
double ans=0;
for(int i=l;i<=r;++i){
ans+=dp[pre][i];
}
cout<<setiosflags(ios::fixed)<<setprecision(4)<<ans<<endl;
}
return 0;
}