POJ 3941

题意:给出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 }

你可能感兴趣的:(poj)