洛谷 SP1026 FAVDICE - Favorite Dice

洛谷 SP1026 FAVDICE - Favorite Dice

洛谷传送门

题目描述

BuggyD loves to carry his favorite die around. Perhaps you wonder why it's his favorite? Well, his die is magical and can be transformed into an N-sided unbiased die with the push of a button. Now BuggyD wants to learn more about his die, so he raises a question:

What is the expected number of throws of his die while it has N sides so that each number is rolled at least once?

输入格式

The first line of the input contains an integer t, the number of test cases. t test cases follow.

Each test case consists of a single line containing a single integer N (1 <= N <= 1000) - the number of sides on BuggyD's die.

输出格式

For each test case, print one line containing the expected number of times BuggyD needs to throw his N-sided die so that each number appears at least once. The expected number must be accurate to 2 decimal digits.

题意翻译

一个n面的骰子,求期望掷几次能使得每一面都被掷到。


题解:

以前拐入了一个求期望的误区,就是数学方法直接按定义来求期望。但是很快思路就卡死了,因为数学方法求期望实在不适合数据范围比较大的计算机题。

(还是蒟蒻太菜了啊)

那么应该使用什么方法呢?

DP。

期望DP。

对于期望DP的一般思路,蒟蒻在这篇博客中有着讲解:

浅谈期望DP

那么这道题就是采用的基本期望DP的方程设计思路和动规转移思路:设置dp[i]表示已经掷过i面,还期望掷几次能掷完n面。这也是期望DP的一个基础的转移方程设计思路,就是表示由i状态变成最终状态的期望

转移的时候考虑两种情况的贡献和:第一种情况是再掷的时候掷到已经掷过的面。第二种情况是再掷的时候掷到新面。那么转移方程也就是:

\[dp[i]=\frac{i}{n}dp[i]+\frac{n-i}{n}dp[i+1]+1 \]

化简:

\[dp[i]=dp[i+1]+\frac{n}{n-i} \]

然后转移的时候使用刷表法,也就是逆向枚举。因为初值是dp[n]=0,答案是dp[0]。

关于填表和刷表,蒟蒻的理解:

填表法和刷表法

代码:

#include<cstdio>
#include<cstring>
using namespace std;
int t;
int n;
double dp[1010];
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        memset(dp,0,sizeof(dp));
        scanf("%d",&n);
        for(int i=n-1;i>=0;i--)
            dp[i]=dp[i+1]+(double)n/(n-i);
        printf("%.2lf\n",dp[0]);
    }
    return 0;
}
posted @ 2020-10-19 09:33  Seaway-Fu  阅读(130)  评论(0编辑  收藏  举报