BZOJ 3450 - Tyvj1952 Easy (指望DP)

描述

某一天 WJMZBMR 在打 osu~~~ 可是他太弱逼了,有些地方徹底靠運氣:(
咱們來簡化一下這個遊戲的規則:
\(n(n\le 300000)\) 次點擊要作,成功了就是 o,失敗了就是 x,分數是按 comb 計算的,連續 \(a\) 個 comb 就有 \(a^2\) 分,comb 就是極大的連續 o
好比 ooxxxxooooxxx,分數就是 \(2\times 2+4\times 4=4+16=20\)
Sevenkplus 閒的慌就看他打了一盤,有些地方跟運氣無關要麼是 o 要麼是 x,有些地方 o 或者 x 各有 \(50\%\) 的可能性,用 ? 號來表示。
那麼 WJMZBMR 這場 osu 的指望得分是多少呢?spa

思路:

這個題若是一段一段的處理,實際上並非很好作。咱們觀察到 \((x + 1) ^ 2 - x ^ 2 = 2x + 1\),那麼根據指望的線性性質,咱們能夠單獨算每個字符的貢獻。咱們設 \(dp_i\) 爲考慮前 ii 個字符的指望得分,\(l_i\) 爲以 \(i\) 爲結尾的 comb 的指望長度,\(Comb_i\) 爲第 \(i\)個字符,那麼有 3 種狀況:code

  1. \(s_i = o\) ,則 \(dp_i = dp_{i - 1} + l_{i - 1} * 2 + 1,l_i = l_{i - 1} + 1\)
  2. \(s_i = x\) ,則 \(dp_i = dp_{i - 1}\)
  3. \(s_i =\ ?\), 則 \(dP_i = dp_{i - 1} + \frac{l_i*2 + 1}{2},l_i = \frac{l_{i - 1} + 1}{2}\)

對於前兩種狀況,實際上是很是直觀的,對於第三種狀況,其實是求了一個平均長度。例如 ?oo,兩種狀況的長度 \(l_i\) 分別爲 \([0,1,2]\)\([1,2,3]\) ,可是求了平均以後,長度 \(l_i\) 變成了 \([0.5,1.5,2.5]\) ,這樣因爲咱們的貢獻是一個關於長度的一次多項式 \((2x + 1)\) ,因此長度平均以後,貢獻也至關於求了一個平均,天然可以求得正確的得分指望。遊戲

【AC Code】ip

const int N = 3e5 + 10;
double dp[N], Comb[N];
int main() {
    cin.tie(nullptr)->sync_with_stdio(false);
    int n; string s;
    cin >> n >> s;
    for (int i = 0; i < n; ++i) {
        if (s[i] == 'o') {
            dp[i] = dp[i - 1] + Comb[i - 1] * 2 + 1;
            Comb[i] = Comb[i - 1] + 1;
        } else if (s[i] == 'x') {
            dp[i] = dp[i - 1];
            Comb[i] = 0;
        } else {
            dp[i] = dp[i - 1] + (Comb[i - 1] * 2 + 1) / 2;
            Comb[i] = (Comb[i - 1] + 1) / 2;
        }
    }
    cout << setprecision(4) << fixed << dp[n - 1];
}

思考:若是長度爲 \(a\) 的 comb 的貢獻爲 \(a^3\) 時該如何解決?題目連接:Hereci

Tips:因爲 \((a + 1)^3 - a^3 = 3a^3 + 3a + 1\) ,因此咱們要維護 \(a^2\)\(a\) 的指望,注意 \(E_{a^2} \not= E^2_a\),因此維護 \(a^2\) 的指望是必要的。get

相關文章
相關標籤/搜索