题意:给出n个有m面的骰子,扔一次,求出和,如果和小于等于k,就记1,否则就是和减去k,求最后期望。
题解:用滚动数组dp[2][MAX]记录当前扔到某个数的情况种数,然后......挺水的。。
View Code
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 using namespace std; 6 const int N=10005; 7 int dp[2][N]; 8 int main() 9 { 10 int n,m,k; 11 while(scanf("%d%d%d",&n,&m,&k),n||m||k) 12 { 13 double all=pow((double)m,double(n)); 14 memset(dp,0,sizeof(dp)); 15 for(int i=1;i<=m;i++) 16 dp[0][i]=1; 17 int mmax=n*m; 18 double sum=0; 19 for(int i=2;i<=n;i++) 20 { 21 int a=i&1,b=a^1; 22 memset(dp[b],0,sizeof(dp[b])); 23 for(int j=mmax;j>=1;j--) 24 for(int t=1;t<=m&&t<j;t++) 25 dp[b][j]+=dp[a][j-t]; 26 } 27 int no=(n+1)&1; 28 for(int i=1;i<=k+1;i++) 29 sum+=(double)dp[no][i]; 30 for(int i=k+2;i<=mmax;i++) 31 sum+=(double)dp[no][i]*(i-k); 32 printf("%.8lf\n",sum/all); 33 } 34 return 0; 35 }