1. 程式人生 > 其它 >第46屆ICPC亞洲區域賽(昆明)題解

第46屆ICPC亞洲區域賽(昆明)題解

C. Cup of Water

題意

每次會在\([0,a]\)之間隨機選一個數\(t\),往水桶裡裝\(t\)升水,問使得水桶裡的水大於等於\(1\)升的期望最少次數。其中\(0.05\leq a\leq 10^9\)

方法一

利用多重積分可以證明,\(n\)維下,有\(n\)條長度為\(x\)的邊且它們互相垂直的物體(下稱單純形)的\(n\)維測度為

\[V_n=\frac{x^n}{n!} \]

對於區域\(x_1+x_2+\dots+x_n\leq1\)\(0\leq x_i\leq a\)的交集的測度可以使用容斥原理計算。

\(x_1,x_2,\dots,x_n\geq 0\)的條件下,

任選\(0\)個變數,令其大於\(a\),其餘無額外約束,表示至少有\(0\)個變數大於\(a\),共有\(\binom{n}{0}\)種選法,所以要加上\(\binom{n}{1}\)個長度為\(1\)的單純形的測度

任選\(1\)個變數,令其大於\(a\),其餘無額外約束,表示至少有\(1\)個變數大於\(a\),共有\(\binom{n}{1}\)種選法,所以要減去\(\binom{n}{1}\)個長度為\(1-a\)的單純形的測度

任選\(2\)個變數,令其大於\(a\),其餘無額外約束,表示至少有\(2\)個變數大於\(a\),共有\(\binom{n}{2}\)種選法,所以要加上\(\binom{n}{2}\)

個長度為\(1-2a\)的單純形的測度

\(\dots\)

直到任選\(i\)個變數時,\(1-ia<0\),不存在有\(i\)個變數同時大於\(a\)的可能,計算結束,故式子如下

\[V_n=\sum\limits_{i=0}^{\lfloor\frac{1}{a}\rfloor}\frac{(-1)^{i}}{n!}\binom{n}{i}(1-ia)^n \]

計隨機變數\(X\)為每次均勻隨機走\([0,a]\),達到大於等於\(1\)所需的最少次數,則有

\[\begin{aligned} P(X\leq k)&=1-\frac{1}{a^k}\sum\limits_{i=0}^{\lfloor\frac{1}{a}\rfloor}\frac{(-1)^{i}}{k!}\binom{k}{i}(1-ia)^k\\ &=1-\sum\limits_{i=0}^{\lfloor\frac{1}{a}\rfloor}\frac{(-1)^{i}}{k!}\binom{k}{i}\left(\frac{1}{a}-i\right)^k \end{aligned} \]

由此可得

\[\begin{aligned} P(X = k)&=P(X \leq k) - P(X \leq k-1)\\ &=\sum\limits_{i=0}^{\lfloor\frac{1}{a}\rfloor}\frac{(-1)^{i}}{(k-1)!}\binom{k-1}{i}\left(\frac{1}{a}-i\right)^{k-1}-\sum\limits_{i=0}^{\lfloor\frac{1}{a}\rfloor}\frac{(-1)^{i}}{k!}\binom{k}{i}\left(\frac{1}{a}-i\right)^k \end{aligned} \]

故期望為

\[\begin{aligned} E(X)&=\sum\limits_{k=1}^{\infty}kP(X=k)\\ &=\sum\limits_{k=1}^{\infty}k\left(\sum\limits_{i=0}^{\lfloor\frac{1}{a}\rfloor}\frac{(-1)^{i}}{(k-1)!}\binom{k-1}{i}\left(\frac{1}{a}-i\right)^{k-1}-\sum\limits_{i=0}^{\lfloor\frac{1}{a}\rfloor}\frac{(-1)^{i}}{k!}\binom{k}{i}\left(\frac{1}{a}-i\right)^k\right)\\ &=\sum\limits_{k=0}^{\infty}\sum\limits_{i=0}^{\lfloor\frac{1}{a}\rfloor}\frac{(-1)^{i}}{k!}\binom{k}{i}\left(\frac{1}{a}-i\right)^k\\ &=\sum\limits_{i=0}^{\lfloor\frac{1}{a}\rfloor}\sum\limits_{k=0}^{\infty}\frac{(-1)^{i}}{k!}\binom{k}{i}\left(\frac{1}{a}-i\right)^k\\ &=\sum\limits_{i=0}^{\lfloor\frac{1}{a}\rfloor}\frac{(-1)^i}{i!}\sum\limits_{k=0}^{\infty}\frac{1}{(k-i)!}\left(\frac{1}{a}-i\right)^k\\ &=\sum\limits_{i=0}^{\lfloor\frac{1}{a}\rfloor}\frac{(-1)^i}{i!}\left(\frac{1}{a}-i\right)^{i}\sum\limits_{k=0}^{\infty}\frac{1}{(k-i)!}\left(\frac{1}{a}-i\right)^{k-i}\\ &=\sum\limits_{i=0}^{\lfloor\frac{1}{a}\rfloor}\frac{(-1)^i}{i!}\left(\frac{1}{a}-i\right)^{i}\mathrm{e}^{\frac{1}{a}-i} \end{aligned} \]

方法二

\(f(x)\)為每次均勻隨機走\([0,a]\),達到大於等於\(x\)的期望次數,由全期望公式

\[f(x)=\int_{x-a}^x\left(\frac{f(t)+1}{a}\right)\mathrm{d}t=1+\int_{x-a}^x\frac{f(t)}{a}\mathrm{d}t \]

兩側對\(x\)求導

\[af'(x)=f(x)-f(x-a) \]

對於這個式子,有兩種處理辦法,一種是利用導數的定義進行近似計算,另一種是像方法一那樣,通過這個式子,推出最終結果的式子。

法一

進行近似計算,當\(\Delta x\to 0\)時,有

\[a\cdot \frac{f(x+\Delta x)-f(x)}{\Delta x}=f(x)-f(x-a)\\ f(x+\Delta x)=f(x)+\frac{\Delta x}{a}(f(x)-f(x-a))\\ \]

令初值\(f(0)=1\)\(f(1)\)即為答案

由於題目是多組輸入,且步長\([0,a]\),大於等於\(1\)的期望步數,等價於,步長\([0,1]\),大於等於\(\frac{1}{a}\)的期望步數,故而把遞推式變成

\[f(x+\Delta x)=f(x)+\Delta x(f(x)-f(x-1))\\ \]

令初值\(f(0)=1\)\(f(\frac{1}{a})\)即為答案,這樣在多組輸入之前就可以進行預處理。

法二

像法一一樣先轉化為步長為\([0,1]\)的問題,遞推式變成

\[f'(x)=f(x)-f(x-1) \]

\(x\)範圍進行分類討論

  1. \(0<x\leq 1\)時,\(f(x-1)=0\)

    解得\(f(x)=C\mathrm{e}^x\)

    \(x\to 0^+\)時,\(f(x)\to1\),故\(C=1\)

    \(f(x)=\mathrm{e}^x\)

  2. \(1<x\leq 2\)時,\(f(x-1)=\mathrm{e}^{x-1}\)

    解得\(f(x)=C\mathrm{e}^x-x\mathrm{e}^{x-1}\)

    由連續性,當\(x\to 1^+\)時,\(f(x)\to f(1)=\mathrm{e}\),故\(C=1+\frac{1}{e}\)

    \(f(x)=\mathrm{e}^x-(x-1)\mathrm{e}^{x-1}\)

  3. \(2<x\leq 3\)時,\(f(x-1)=\mathrm{e}^{x-1}-(x-2)\mathrm{e}^{x-2}\)

    解得\(f(x)=C\mathrm{e}^x-x\mathrm{e}^{x-1}+\frac{1}{2}(x-2)^2\mathrm{e}^{x-2}\)

    由連續性,當\(x\to 2^+\)時,\(f(x)\to f(2)=\mathrm{e}^2-\mathrm{e}\),故\(C=1+\frac{1}{e}\),

    \(f(x)=\mathrm{e}^x-(x-1)\mathrm{e}^{x-1}+\frac{1}{2}(x-2)^2\mathrm{e}^{x-2}\)

\(\dots\)

找規律,並數歸可得,當\(k<x\leq(k+1)\)時(\(k\)為非負整數)

\[f(x)=\sum\limits_{i=0}^k\frac{(-1)^i}{i!}(x-i)^i\mathrm{e}^{x-i} \]

\(x=\frac{1}{a}\),得

\[f(x)=\sum\limits_{i=0}^{\lfloor\frac{1}{a}\rfloor}\frac{(-1)^i}{i!}\left(\frac{1}{a}-i\right)^i\mathrm{e}^{\frac{1}{a}-i} \]

程式碼

代式子

#include <cmath>
#include <cstdio>
void solve() {
    double x;
    scanf("%lf", &x);
    x = 1 / x;
    double ans = 0, fac = 1;
    for (int i = 0; i < x; i++) {
        if (i & 1)
            ans -= fac * pow(x - i, i) * exp(x - i);
        else
            ans += fac * pow(x - i, i) * exp(x - i);
        fac /= (i + 1);
    }
    printf("%.10lf\n", ans);
}
int main() {
    int T;
    scanf("%d", &T);
    while (T--) solve();
    return 0;
}

近似計算

#include <algorithm>
#include <cmath>
#include <cstdio>
using namespace std;
const int maxn = 1e5;
const double dx = 1.0 / maxn;
double f[maxn * 20 + 100];
void solve() {
    double x;
    scanf("%lf", &x);
    int t = 1 / x * maxn;
    printf("%.10lf\n", f[t]);
}
int main() {
    f[0] = 1;
    for (int i = 0; i < 20 * maxn + 99; i++)
        f[i + 1] = f[i] + dx * (f[i] - (i - maxn >= 0 ? f[i - maxn] : 0));
    int T;
    scanf("%d", &T);
    while (T--)
        solve();
    return 0;
}