POJ Problem 3941 Expected Allowance

来源:互联网 发布:java final void 编辑:程序博客网 时间:2024/06/05 18:33

现有n个m面的骰子,Ujisato要掷这些骰子,他所获得的钞票数是这些骰子的点数之和减去k。而且即使点数之和小于k,Ujisato也能得到一张钞票。假设骰子的每一面的点数为1到m,投得每一面的概率是相等的。

动态规划思想:

设dp[i%2][j]表示投第i(0<=i<n)个骰子时,骰子点数之和为j总共有多少种情况。

#include<iostream>#include<vector>#include<math.h>#include<stdio.h>using namespace std;int main(){    int n, m, k;    while(cin >> n >> m >> k){        if(n == 0 && m == 0 && k == 0)            break;        vector<vector<int> > dp(2);        dp[0].resize(n*m+1);        dp[1].resize(n*m+1);        dp[0][0] = 0;        for(int i = 1; i <= m; ++i)            dp[0][i] = 1;        for(int i = m+1; i <= n*m; ++i)            dp[0][i] = 0;        for(int i = 1; i < n; ++i){            for(int j = 0; j <= n*m; ++j)                dp[i%2][j] = 0;            for(int p = 1; p <= n*m; ++p)                for(int j = 1; j <= m && j < p; ++j)                    dp[i%2][p] += dp[1-i%2][p-j];        }        int sum = 0;        for(int i = 1; i <=k ; ++i)            sum += dp[(n-1)%2][i];        for(int i = k+1; i <= n*m; ++i)            sum += (i-k)*dp[(n-1)%2][i];        int total = pow(1.0*m, 1.0*n);        double ans = (double)(1.0*sum)/total;        printf("%.8f\n", ans);    }    return 0;}


0 0
原创粉丝点击