/*********************复制来的大致题意**********************
有N个数字,M个操作, 区间L, R。 然后问经过M个操作后落在[L, R]的概率。
*******************************************************/
//自己做,错掉了,然后参考了别人的解法,说是要 概率dp
//概率模拟题,一定要用概率来模拟,
//因为数据很大,可能超了__int64,
//模拟方式用dp[2][], 0表示前一个状态,1表示现在的状态,
//WA掉的解法:
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; int main() { int n,m,l,r,w,i,j; __int64 a[210],a1[210]; int temp1,temp2,temp; __int64 fenzi,fenmu; while(scanf("%d%d%d%d",&n,&m,&l,&r)!=EOF) { if(n==0&&m==0&&l==0&&r==0)break; memset(a,0,sizeof(a)); memset(a1,0,sizeof(a1)); a[1]=1; a1[1]=1; for(i=0;i<m;i++) { scanf("%d",&w); w=w%n; for(j=1;j<=n;j++) { if(a[j]!=0) { temp=a[j]; temp1=j+w; while(temp1>n)temp1=temp1-n; temp2=j-w; while(temp2<1)temp2=temp2+n; a1[temp1]+=a[j]; a1[temp2]+=a[j]; a1[j]=a1[j]-temp; } } for(j=1;j<=n;j++) { a[j]=a1[j]; } } fenzi=0; fenmu=0; for(j=1;j<=n;j++) { fenmu=fenmu+a[j]; } for(j=l;j<=r;j++) { fenzi=fenzi+a[j]; } printf("%.4lf ",(fenzi*1.0)/(fenmu*1.0)); } return 0; }
//我猜测搓掉的原因是数据太大,导致越界,然后结果就不准了,因为m很大哦~
//可以AC的解法:
//听说这种解法叫做简单的概率dp #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; int main() { int n,m,l,r,w,i,j; int temp1,temp2,temp; double dp[2][210]; //0 1 表示前后两次,210 表示点 dp 概率 while(scanf("%d%d%d%d",&n,&m,&l,&r)!=EOF) { if(n==0&&m==0&&l==0&&r==0)break; memset(dp,0,sizeof(dp)); dp[0][1]=1; temp = 0; //状态 0 1 for(i=1;i<=m;i++) { scanf("%d",&w); for(j=1;j<=n;j++) { temp1=j+w; while(temp1>n)temp1=temp1-n; temp2=j-w; while(temp2<1)temp2=temp2+n; dp[(temp+1)%2][temp1]+=dp[temp][j]*0.5; dp[(temp+1)%2][temp2]+=dp[temp][j]*0.5; dp[temp][j]=0; } temp=(temp+1)%2; } double ans = 0.0; for(i=l;i<=r;i++) { ans+=dp[temp][i]; } printf("%.4lf ",ans); } return 0; }