题解【OSU!_BZOJ4318】(洛谷P1654)

题意

\(n\)个字符,每个字符有\(A_i\)的概率为\(1\),否则为\(0\)。这样可以构成一个\(01\)串,对于其中一个极长的连续为\(1\)的串,它能贡献的得分为这个串的长度的三次方。求最终得分。

分析一下

  • 期望型\(DP\)超级难搞的\(\cdots\),不过状态确定下来就还好啦。
  • \(F1_1\)表示以\(i\)为结尾的\(1\)串的期望长度。\(F2_i\)表示以\(i\)为结尾的\(1\)串期望长度的平方。\(F3_i\)表示以\(i\)结尾的串的得分(注意不是长度的三次方)。
    \[F1_i = (F1_{i-1} +1) \cdot A_i\]
    \(F_2\)的转移可以应用完全平方公式:
    \[F2_i = (F2_{i-1} + 2 \cdot F1_{i-1}+1) \cdot A_i\]
    \(F_3\)的转移因为要考虑第\(i\)位可能为\(0\)所以转移要考虑进去:
    \[F3_i = (F3_{i-1} + 3 \cdot F2_{i - 1} + 3 \cdot F1_{i - 1} + 1) \cdot A_i + F3_{i - 1} \cdot (1 - A_i)\]
  • 然后就没啦~

代码君

#include <iostream>
#include <cstdio>
#include <algorithm>

using namespace std;

int n;
double ar[100005], f1[100005], f2[100005], f3[100005];

int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
        scanf("%lf", &ar[i]);
    for (int i = 1; i <= n; i++) {
        f1[i] = ar[i] * (f1[i - 1] + 1);
        f2[i] = ar[i] * (f2[i - 1] + 2 * f1[i - 1] + 1);
        f3[i] = ar[i] * (f3[i - 1] + 3 * f2[i - 1] + 3 * f1[i - 1] + 1) + (1 - ar[i]) * f3[i - 1];
    }
    printf("%.1lf\n", f3[n]);
    return 0;
} \\注释加不动了...

猜你喜欢

转载自www.cnblogs.com/JackHomes/p/9470677.html