洛谷P4550 收集郵票 題解 期望DP

quanjun發表於2024-09-13

題目連結:https://www.luogu.com.cn/problem/P4550

解題思路:

定義狀態 \(f_i\) 表示目前已經取到 \(i\) 種郵票的情況下,取完所有 \(n\) 種郵票,還需要取的期望次數。

很明顯,\(f_n = 0\),因為此時已經取完了 \(n\) 種郵票,不需要再取就能滿足條件了。

如果當前已經取到了 \(i\) 種郵票,則下一次取:

  • \(\frac{i}{n}\) 的機率取到現有的郵票(此時仍然擁有 \(i\) 種郵票);
  • \(1 - \frac{i}{n}\) 的機率取到沒有的郵票(此時擁有了 \(i+1\) 種郵票)。

所以,當 \(i \lt n\) 時:

\[f_i = \frac{i}{n} f_i + (1 - \frac{i}{n}) f_{i+1} + 1 \]

(多出來的 \(1\) 是額外的操作次數)

化簡得到:

\(\frac{n-i}{n} f_i = \frac{n-i}{n} f_{i+1} + 1\)

\(\rightarrow\)

\(i \lt n\) 時:

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

定義狀態 \(g_i\) 表示目前已經取到 \(i\) 種郵票的情況下,取完所有 \(n\) 種郵票,還需要的期望代價。

"第 \(k\) 次取的花費為 \(k\)"。\(\Rightarrow\) 但是這麼分析會很麻煩,我們可以把問題轉換為 "倒數第 \(k\) 次取的花費為 \(k\)"

這兩句話其實是等價的:

因為假設取 \(m\) 次,那麼:

  • 按照 "第 \(k\) 次取的花費為 \(k\)" 總的花費為 \(1 + 2 + 3 + \ldots + m = \sum\limits_{i=1}^m i\)
  • 按照 “倒數第 \(k\) 次取的花費為 \(k\)” 總的花費為 \(m + (m-1) + (m-2) + \ldots + 2 + 1 = \sum\limits_{i=1}^m i\)$。

但是按照這樣分析,接下來解決起來會好理解很多。這也是我在看 洛谷上的題解 的時候(我感覺)前幾篇題解沒有講的很清楚的地方 後幾篇的題解我沒看

而取到 \(i\) 種不同的郵票的期望次數是 \(f_i\) 次,所以在擁有 \(i\) 種不同郵票的情況下,要取完 \(n\) 種郵票的期望次數是 \(f_i\) 次,所以我:

  • 此時如果取到的是一張現有的郵票,則我還有 \(f_i\) 次要取,我這次的期望取的次數是倒數第 \(f_i + 1\) 次,花費為 \(f_i + 1\)
  • 此時如果取到的是一張新的郵票,則我還有 \(f_{i+1}\) 次要取,我這次的期望取的次數是倒數第 \(f_{i+1} + 1\) 次,花費為 \(f_{i+1} + 1\)

此時我:

  • \(\frac{i}{n}\) 的機率取到現有的郵票(此時仍然擁有 \(i\) 種郵票);
  • \(1 - \frac{i}{n}\) 的機率取到沒有的郵票(此時擁有了 \(i+1\) 種郵票)。

所以,當 \(i \lt n\) 時:

\[g_i = \frac{i}{n} (g_i + f_i + 1) + (1 - \frac{i}{n}) (g_{i+1} + f_{i+1} + 1) \]

化簡得到:

\(\frac{n-i}{n} g_i = \frac{i}{n} (f_i + 1) + \frac{n-i}{n} (g_{i+1} + f_{i+1} + 1)\)

\(\Rightarrow\)

\[g_i = g_{i+1} + f_{i+1} + 1 + \frac{i}{n-i} (f_i + 1) \]

最終的答案為 \(g_0\)

示例程式:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e4 + 5;
double f[maxn], g[maxn];
int n;

int main() {
    cin >> n;
    for (int i = n-1; i >= 0; i--)
        f[i] = f[i+1] + 1. * n / (n - i),
        g[i] = g[i+1] + f[i+1] + 1 + 1. * i / (n - i) * (f[i] + 1);
    printf("%.2lf\n", g[0]);
    return 0;
}

相關文章