题目大意
有一个环n个点,从起点1开始m次操作,每次随机向前向后走w步,求最后在区间[l,r]的概率。
大致思路
每一次能到达的点的概率是出发点概率的1/2,最开始起点概率是1.0。由此可以用dp记录每次到达每个点的概率,复杂度O(n*m),限时4000ms(最终是3600ms)。由于m<=1e6,考虑滚动数组。
训练赛时两个多小时才想到这个思路,有点亏。
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,m,l,r,w;
double dp[2][202];
while(1){
scanf("%d%d%d%d",&n,&m,&l,&r);
if(n==0)break;
memset(dp,0,sizeof(dp));
dp[0][0]=1.0;
for(int i=0;i<m;i++){
scanf("%d",&w);
memset(dp[(i+1)&1],0,sizeof(dp)/2);
for(int j=0;j<n;j++){
if(dp[i&1][j]){
dp[(i+1)&1][(j+w)%n]+=dp[i&1][j]/2.0;
dp[(i+1)&1][(j+n-(w%n))%n]+=dp[i&1][j]/2.0;
}
}
}
double ans=0;
for(int i=l-1;i<r;i++){
ans+=dp[m&1][i];
}
printf("%.4lf\n",ans);
}
return 0;
}