概率期望

概率期望


引:

一个简单问题:

在一条数轴上, 从0点开始, 每一秒有一般的几率向正方向走一个单位, 有一半几率停着不动

问在(0,1)的概率与期望秒数


如果是停留在(0), 可以$f[0] = (f[0] + 1)*0.5 (, 所以)f[0]=1$

也可以(sum^{infty}(frac{1}{2})^i)

但是发现算(1)的时候, 在(n)秒中, 可以随意选择其中一秒走一步, 其他停住, 这样答案算起会很大((sum^{infty}(frac{1}{2})^i*i^2))

显然错了, 因为到达自己之后仍然可以停留, 那么这个事件的定义就不明确了(既不是停留, 又不是到达)

如果是定义第一次到这个点的话, 就不能算自己到自己的这个事件, 这种傻逼问题之后可能又会碰到


基本定义

概率空间
(Omega)
基本事件
(elementray event, 单元事件, 不可再分): (omega)
事件
(event): (A)

(omega in Omega, omega in A, A subseteq Omega)

[P(omega in A)=sum_{omegain A}P(omega) ]

随机变量
(定义在(omega)上): (S), 如(S(omega))定义为两个骰子点数和, 再例如"(事件S(omega)=7的概率)"
独立的随机变量
如果同一个(Omega)中的两个随机变量(X,Y), 有

[P(X=x~and~Y=y)=P(X=x)* P(Y=y) ]

则称(X,Y)为独立的随机变量(这是定义)

套路

考虑每一步对期望的贡献

(n) 个点, 一开始全白, 每次某个概率选一个点染成黑色, 求期望全染黑的步数?

有期望的定义式可得: (Ans = sum_{i > 0} i cdot Pr_{第 i 步恰好全黑})

考虑什么时候会走这个 $i步 , 即第 (i) 步时未全染黑的概率, 因为只要这时未全染黑, 后面无论何时染黑(后面情况加起来概率为1), 都需要走这一步, 所以这一步的贡献 = 概率

套路: 上述期望 = (sum_{i > 0} Pr_{第 i 步没有全黑的概率})


简单题

LightOJ1027 A Dangerous Maze <简单>

假迷宫, 假如门的代价是正数, 就可以花这个代价出去, 否则要花绝对值的代价, 留在原地

问出去的期望

(E = sum frac{1}{n}*cost_i+sum frac{1}{n}*(cost_i + E))

化简即可

int T = in();
    for (int t = 1; t <= T; ++ t)
    {
        n = in();
        int sumx = 0, sumy = 0, cnty = 0, g = 0;
        for (int i = 1; i <= n; ++ i)
        {
            int x = in();
            if (x > 0) sumx += x; else sumy -= x, ++ cnty;
        }
        if (sumx == 0) { printf("Case %d: inf
", t); continue; }
        g = gcd(sumx + sumy, n - cnty);
        printf("Case %d: %d/%d
", t, (sumx + sumy) / g, (n - cnty) / g);
    }

LightOJ1030 Discovering Gold <简单>

金矿有(n)个, 每个金矿有一定收益, 一开始在(1), 投骰子([1,6]), 假如走这些步数后(>n)就一直投直到(le n), 求到(n)时期望收益

	memset(f, 0, sizeof f);
    for (int i = n - 1; i >= 1; -- i)
    {
        int p = min(6, n - i);
        for (int j = 1; j <= p; ++ j)
           f[i] += (f[i + j] + val[i + j]) / (double)p;
    }
    ans = f[1] + val[1];

LightOJ1038 Race to 1 Again <预处理?!>

(T(le 10))组数据, 每次给出(N(le 10^5))

每个数有相同几率跳到他的因数(包括自己), 求跳到(1)的期望步数

(cnt)(i)的因数个数, (f[i]=frac{1}{cnt}*sum f[j]+1)

((1-frac{1}{cnt})f[i]=frac{1}{cnt} sum ^{!=i}f[j]+1)

(f[i]=(sum^{!=i}f[j]+cnt) / (cnt - 1))

所有(10^5)以内都可以一遍(DP)预处理

int T, n;

double dp[MAXN];

void init()
{
    for (int i = 2; i <= 100000; ++ i)
    {
        double sum = 0, cnt = 0;
        for (int j = 1; j * j <= i; ++ j)
        {
            if (i % j != 0) continue;
            sum += dp[j], cnt += 1;
            if (i / j != j) sum += dp[i / j], cnt += 1;
        }
        dp[i] = (sum + cnt) / (cnt - 1);
    }
}

int main()
{
    init();
    T = in();
    for (int i = 1; i <= T; ++ i)
    {
        n = in();
        printf("Case %d: %.6lf
", i, dp[n]);
    }
    return 0;
}

LightOJ1248 Dice (III) <期望初步>

(n)面的均匀的骰子每一面都投到的期望次数

(E_i)表示已经有(i)个不同的面时的期望

那么(E_i = 1 + frac{i}{n}E[i]+frac{n-i}{n}E[i+1])

意思是说: 现在投一次, 有(i/n)的几率投到出现过的, 那么又回到(i)这个点, 还有剩下几率投到新的面

LightOJ1104 Birthday Paradox <正难则反>

求当一年为(n(le 10^5))天时, 至少要多少人, 才能满足他们中至少有两人生日相同的概率(ge 0.5)

Sol:

竟然不会....

至少有两人相同可以转化成(1.0-)所有人都不相同的概率

BZOJ2752: HAOI2012高速公路 <假期望>

(n(le 10^5))个点, 相邻两点之间有边权, 初始是(0)

(M(le 10^5))个询问/操作, 操作是将([l, r])之间的边权都加上一个值, 查询是问在([l,r])中选两个不同的点, 他们之间边权和的期望

Sol:

假期望, 这是所有选择的边权和的和, 让它取除以方案数( binom{r-l+1}{2})

[egin{align} &=sum_{i=l}^{r}sum[i]*(i-l)-sum_{i=l}^{r}sum[i]*(r-i)\ &=sum_{i=l}^{r}sum[i]*(i-l-r+i)\ &=sum_{i=l}^{r}sum[i]*(2*i-r-l)\ end{align} ]

中等

LightOJ1151 Snakes and Ladders <高斯消元>

自以为思路很正确, 实则漏洞百出

(1*100)的棋盘上, 每个点至多有一个单向传送, 起点和终点不会有传送

可以扔一个(6)面的骰子, 假设投到(x), 然后花一步跳到往后数(x)个格子上, 如果超过(100)就重新投(但是要花费步数)

问期望几次从(1)到达(100)

Sol:

因为传送是xjb乱传的, 不能递推, 用高斯消元

考虑期望方程(读清题意!!!)

能传送和不能传送的点是不同的, 能传送的点根本就不能有任何操作直接传送到那个点!!!

能传送:

[E_{now}=E{nex} ]

不能传送:

[E_{now}=1+frac{1}{6}*(sum_{nex<=100}E_{nex} + min(0, i+6-100)*E_{now}) ]

可以根据这些列出方程

int n, to[MAXN];
DB a[MAXN][MAXN];
DB ansx[MAXN];

void check(int n)
{
    puts("------");
    for (int i = 1; i <= n; ++ i)
    {
        for (int j = 1; j <= n + 1; ++ j)
            printf("%.1f ", a[i][j]);
        puts("");
    }
    puts("------");
}
bool nosol, mulsol;
void Gauss(int n) 
{
    int r = 1, c = 1, maxr = 0;
    for (; r <= n && c <= n; ++ r, ++ c)
    {
        maxr = r;
        for (int i = r + 1; i <= n; ++ i) 
            if (fabs(a[i][c]) - fabs(a[maxr][c]) > EPS) maxr = i;
        if (maxr != r) 
            for (int i = 1; i <= n + 1; ++ i) // n + 1 !!!
                swap(a[r][i], a[maxr][i]);
        if (fabs(a[r][c]) < EPS) { -- r; continue; }
        for (int i = r + 1; i <= n; ++ i)
        {
            double k = a[i][c] / a[r][c];
            for (int j = c; j <= n + 1; ++ j) 
                a[i][j] = a[i][j] - k * a[r][j];
        }
    }
    -- r, -- c;
    for (int i = n; i >= 1; -- i)
    {
        int all0 = 1;
        for (int j = i; j <= n; ++ j) all0 &= (fabs(a[i][j]) < EPS);
        if (all0)
        {
            if (fabs(a[i][n + 1]) > EPS) nosol = true;
            else mulsol = true;
        }
        else 
        {
            for (int j = i + 1; j <= n; ++ j)
                a[i][n + 1] -= ansx[j] * a[i][j];
            ansx[i] = a[i][n + 1] / a[i][i];
        }
    }
} 

int main()
{
    int T = in();
    for (int t = 1; t <= T; ++ t)
    {
        memset(ansx, 0, sizeof ansx);
        memset(a, 0, sizeof a);
        memset(to, 0, sizeof to);
        n = in();
        for (int i = 1; i <= n; ++ i)
        {
            int x = in(), y = in();
            to[x] = y;
            a[x][x] = 1; a[x][y] = -1;
        }
        for (int i = 1; i <= 100 - 1; ++ i)
        {
            if (to[i]) continue;
            a[i][i] = min(6, 100 - i);
            for (int x = 1; x <= min(6, 100 - i); ++ x)
                a[i][i + x] = -1;
            a[i][101] = 6;
        }
        a[100][100] = 1;
        Gauss(100);
        printf("Case %d: %.7f
", t, ansx[1]);
    }
    return 0;
}

LightOJ 1079 Just another Robbery <正难则反>

(100) 组数据, 每组(le 100)个银行, 每个银行有一个被抓住的几率, 和成功时获得的收益((le 100))

问当总的被抓的几率(le lim)时能获得的最大收益

其实算没被抓的几率就可以了

也可以像我一样傻逼的算被抓的几率:

  • 证明以不同顺序抢同一些银行被抓的几率相同
    • 列一下式子, 发现是容斥, 证毕
  • 证明抢一组银行的被抓/没被抓的几率可以整合, 视作一个合体银行
    • 被抓=(a+(1-a)*b+(1-a)*(1-b)*c=P_{ab}+(1-P_{ab})*c)
    • 展开发现一样, 也是容斥, 或者感性理解也行

好了, 滚动(一开始忘记)背包, 下标是收益

for (int k = 1; k <= T; ++ k)
    {
        sum = ans = tot = 0;
        scanf("%lf%d", &lim, &n);
        for (int i = 0; i <= 10000; ++ i) f[i] = 1; f[0] = 0;
        for (int i = 1; i <= n; ++ i)
        {
            int x; double y;
            scanf("%d%lf", &x, &y);
            if (y <= lim) 
            {
                ++ tot;
                c[tot] = y, v[tot] = x;
                sum += x;
            }
        }
        for (int i = 1; i <= tot; ++ i)
            for (int j = sum; j >= v[i]; -- j)
                f[j] = min(f[j], f[j - v[i]] + (1 - f[j - v[i]]) * c[i]);
        for (int i = sum; i >= 0; -- i)
            if (f[i] <= lim) { ans = i; break; }
        printf("Case %d: %d
", k, ans);
    }

XJOI20190725T3游戏 <假博弈真期望>

Alice和Bob两个人正在玩一个游戏,游戏有很多种任务,难度为p的任务(p是正整数),有1/(2p)的概率完成并得到2(p-1)分,如果完成不了,得0分。一开始每人都是0分,从Alice开始轮流做任务,她可以选择任意一个任务来做;而Bob只会做难度为1的任务。只要其中有一个人达到n分,即算作那个人胜利。求Alice采取最优策略的情况下获胜的概率。

输入格式:

一个正整数n,含义如题目所述。

输出格式:

一个数,表示Alice获胜的概率,保留6位小数。

样例输入:

1

样例输出:

0.666667

数据范围:

对于30%的数据,n≤10

对于100%的数据,n≤500

乍一看以为是博弈论

没想到是枚举所有状态进行概率(DP)

(DP[i][j])表示(A, B)分别为(i,j)时到达赢的状态的概率, 倒着推

那就枚举所有的任务来转移, 取其中最大的转移

(DP[x][y]|xge n ~and~yge n)全部设成(1.0), 这样就不用考虑边界要不要乘(B)的概率的问题(想想为什么?)

for (int i = 1; i <= 10; ++ i) 
        val[i] = 1 << (i - 1), p[i] = 1 << i;
    n = in();
    for (int j = n; j <= 1024; ++ j)
        for (int i = 0; i <= n; ++ i) 
            dp[j][i] = 1.0;
    for (int i = n - 1; i >= 0; -- i)
    {
        for (int j = n - 1; j >= 0; -- j)
        {
            double tmp = 0.0;
            for (int x = 1; x <= 10; ++ x)
            {
                tmp = max(tmp, ((dp[i + val[x]][j + 1] + dp[i + val[x]][j]) * 1.0 / (double)p[x] * 0.5 
                                + dp[i][j + 1] * (1.0 - 1.0 / (double)p[x]) * 0.5)
                          / (1.0 - (1.0 - 1.0 / (double)p[x]) * 0.5));
            }
            dp[i][j] = tmp;
        }
    }
    printf("%.6f
", dp[0][0]);

难题

LightOJ - 1395 A Dangerous Maze (II) <!!!SO HARD!!!>

好题

题意概述:

你在一个迷宫里(假), 起点有(n(le 100))个门

走一个门有个代价(x_i (1le abs(x_i)le10000)), 如果是正数, 就可以花费这个代价离开迷宫, 如果是负数, 花费代价的绝对值, 仍然停留在原地

但是你只能记住最后访问的(k(le 100))个门, 你不会走这些门(因为你还待在迷宫里, 意味着那些门不能出去), 而其他门是随机选择的

问期望离开迷宫的代价

Sample Input

4

2 0
10 10
 
2 0
10 -10

3 1
10 -10 -20 

3 2
10 -10 -20

Sample Output

Case 1: 10
Case 2: 20.000
Case 3: 30.0000000000
Case 4: 25.0000000000

Sol:

先考虑没有记忆的情况, 即每次都随机选门, 设能出去的门个数为(x), 不能出去的为(y)

则期望

[egin{align} E &= sum (frac{x_i}{n})+sum(frac{y_i+E}{n}) \ &= frac{1}{n}*sum x_i+frac{1}{n}*sum y_i + frac{cnt_y}{n}*E \ (1 - frac{cnt_y}{n})*E &= frac{1}{n}*(sum x_i+sum y_i) end{align} ]

那么有记忆呢?

  • 首先(k = min(n,k))

假设当前记住的状态为(now), 记住了(i)

这是候选项是(n - i), 不能出去的门还剩(y-i)

[E[i][now] = frac{1}{n-i}sum x + frac{1}{n-i}sum (y_{remain} + E[i+1][nex]) ]

(k=i)时略有不同

[E[k][now] = frac{1}{n-i}sum x + frac{1}{n-i}sum (y_{remain} + E[k][nex]) ]

可以发现因为这些式子加好后面枚举了剩下的门, 所以这些期望方程大概形成了树型的关系

但是每个状态不同, 剩下的门也不同, 怎么办

可以把树上同一层的式子(E[i])加起来, 把(E[i])作为一个整体来算

感性发现因该是

[E[i]= frac{1}{n-i}sum x + frac{y-i}{n-i}(frac{sum y}{cnty} + E[i+1]) ]

倒着推就行了, 理性证明见这里

int T, n, m;
int x, y;
double sumx, sumy;
double p[106];

int main()
{
    scanf("%d", &T);
    for (int tnum = 1; tnum <= T; ++ tnum)
    {
        x = y = 0; sumx = sumy = 0.0;
        n = in(), m = in();
        p[0] = 0.0;
        for (int i = 1; i <= n; ++ i)
        {
            p[i] = 0.0;
            int tmp = in();
            if (tmp >= 0) ++ x, sumx += tmp;
            else ++ y, sumy -= tmp;
        }
        if (y == 0) { printf("Case %d: %.9f
", tnum, sumx / (double)x); continue; }
        if (x == 0) { printf("Case %d: -1
", tnum); continue; }
        m = min(m, y); 
        p[m] = (double)(sumx + (y - m) * sumy / (double)y) / (double)(n - m) / (1.0 - (double)(y - m) / (double)(n - m)) ;
        for (int i = m - 1; i >= 0; -- i)
        	p[i] = (sumx + (double)(y - i) * (sumy / (double)y + p[i + 1])) / (double)(n - i);
        printf("Case %d: %.9f
", tnum, p[0]);
    }
    return 0;
}

BZOJ1076: [SCOI2008]奖励关 <较难>

发放(k(le 100))轮宝物, 每次随机发放(n(le 15))个宝物其中一个, 即每次对于所有宝物几率都为(frac{1}{n})

宝物的价值可能为负((in [-10^6, 10^6])), 并且拿取宝物有先决条件, 要满足当前已经有某些宝物

你可以决策收不收取这轮的宝物(不满足先决条件时一定不能收取), 求在所有可能的情况下最优决策得到的平均价值

Sol:

最有决策的平均价值是什么意思?

即对于当前这个状态, 有(n)种转移, 每种转移又有取与不取两种决策, 最优决策当然是取收益大的那个决策, 而平均价值则是把每个转移两个里较大的那个加起来, 再除以(n)

要怎么知道转移后收不收取那个更优呢? 想到了倒着推

(f[i][sta])表示到第(i)轮时, 每个宝物是否拥有的情况为(sta), 到末状态的最优决策的平均价值

//BZOJ MLE返回TLE	
scanf("%d%d", &m, &n);
    for (int i = 1; i <= n; ++ i)
    {
        scanf("%d", &val[i]);
        while (true)
        {
            int x; scanf("%d", &x);
            if (!x) break;
            prem[i] |= (1 << (x - 1));
        }
    }
    for (int i = m - 1; i >= 0; -- i)
    {
        for (int now = 0; now < (1 << n); ++ now)
        {
            for (int j = 1; j <= n; ++ j)
            {
                if ((now | prem[j]) != now) f[i][now] += f[i + 1][now];
                else f[i][now] += max(f[i + 1][now | (1 << (j - 1))] + val[j], f[i + 1][now]);
            }
            f[i][now] /= (double)n;
        }
    }
    printf("%.6f
", f[0][0]);

BZOJ1426 收集邮票 <辅助期望>

神题:

有n种不同的邮票,每次只能买一张,并且买到的邮票究竟是n种邮票中的哪一种是等概率的,概率均为1/n,购买第k张邮票需要支付k元钱。
求得到所有种类的邮票需要花费的钱数目的期望。

input
3
output
21.25

Sol:

(f[i])为有了(i)张时, 期望再买几次能凑齐, (g[i])为...时期望代价

(f[i]=frac{i}{n}f[i]+frac{n-i}{n}f[i+1]+1)
(g[i]=frac{i}{n}(g[i]+f[i]+1)+frac{n-i}{n}(g[i+1]+f[i+1]+1))

即把当前花费当做(1), 其他一次增长, 因为反正都是花费这些数, 知道总共花费几次, 花费的顺序是无所谓的

BZOJ2830: SHOI2012 随机树 <树上子问题>

初始树上只有一个点, 定义根节点深度为(0)
每次操作随机选择一个叶子, 给他增加两个儿子

求有(n)个叶子时, 叶子深度的平均值的期望, 和树深度的期望

Sol:

乍一看以为第一问比较难, 其实他比较简单

第二问:
显然是DP, 这种题在于如何选择DP的状态, 以及选择算期望/算概率, 还有借用辅助的概率/期望, 如果定义好了DP, 那么推一下是不难的

一开始想了几种一维的DP(每次要么选择最深点, 深度++, 否则深度不变), 还想过借用算大小为(i)的树深度为(j)的叶子个数的期望值来推, 都不行

观察一下这道题, 期望的深度是实数, 而对于每一种可能他的深度是整数, 而概率是实数, 不妨计算每一个深度出现的概率

如果想到左右子树分别是一个子问题的话, 这道题目就好做了, 而不是把所有叶子节点根据深度分类, 这样并不能简化问题

(f[i][j])表示叶子有(i)个时, 深度是(j)的概率, 那么枚举左右字数叶子个数以及深度, 再加一个前缀和优化即可

double g[MAXN];
double f[MAXN][MAXN], p[MAXN][MAXN], t[MAXN][MAXN];
double solve(int n)
{
    p[1][1] = 1;
    for (int i = 3; i <= n; ++ i)
    {
	for (int j = 1; j < i; ++ j)
	{
	    if (j > 1) p[j][i - j] += p[j - 1][i - j] * (DB)(j - 1);
	    if (i - j > 1) p[j][i - j] += p[j][i - j - 1] * (DB)(i - j - 1);
	    p[j][i - j] /= (double)(i - 1);
	}
    }
    f[1][0] = t[1][0] = 1.0; f[2][1] = 1.0;
    for (int i = 1; i <= n; ++ i) t[1][i] = t[2][i] = 1.0;
    for (int i = 3; i <= n; ++ i)
    {
	for (int j = 1; j < i; ++ j)
	{
	    for (int ls = 1; ls < i; ++ ls)
	    {
		if (j > 1) 
		    f[i][j] += (f[ls][j - 1] * t[i - ls][j - 2] + f[i - ls][j - 1] * t[ls][j - 2]) * p[ls][i - ls];
		f[i][j] += f[ls][j - 1] * f[i - ls][j - 1] * p[ls][i - ls];
	    }
	    t[i][j] = t[i][j - 1] + f[i][j];
	}
	for (int j = i; j <= n; ++ j) t[i][j] = t[i][j - 1] + f[i][j];
    }
    double ret = 0;
    for (int i = 1; i < n; ++ i) ret += 1.0 * i * f[n][i];
    return ret;
}

int main()
{
    m = in(); n = in();
    for (int i = 2; i <= n; ++ i) g[i] = g[i - 1] + 2 / (1.0 * i);
    if (m == 1) printf("%.6f
", g[n]);
    else printf("%.6f
", solve(n));
    return 0;
}

Codeforces 235B Let's Play Osu!

有长度为(n)(01)串, 第(i)个位置有(pi)的几率是(1), 否则为(0)
一个串的值为每一段最长连续的(1)的长度的平方的和

求期望值

20191002 Cyanic Contest Problem C. Fibonacci’s Nightmare <推式子>

定义一个随机线性递推序列(即random linear recursive sequence, RLRS)是一个由如下方式生成的非负整数序列。一开始,令(a_0= 1)。然后对于从(1)开始的每一个(n),独立且等概率在([0, n−1])中随机(k)个非负整数(i_1, i_2,···, i_k,)(a_n=∑^k_{j=1}a_{i_j})。接下来是一个例子。令(k= 2),那么有(a_1=a_0+a_0= 2),之后,(a_2)的值等概率从(a_0+a_0, a_0+a_1, a_1+a_0, a_1+a_1)中选择。小C解决了(k= 2)(a^2_n)的数学期望。她想问你对于更大的(k)(E(a^k_n))在模(998244353)下的值

这里的(E(a^k_n))((a_n)^k)的期望

Sol:
对于(k=2)
(f(n) = E((a_n)^2))

[f(n) = E((a_i+a_j)^2)=E(a_i^2+a_j^2+2a_ia_j) ]

发现还需要一个(g(n)=E(sum_{i=0}^{n}a_i^2),t(n)=E(sum_{i=0}^{n}sum_{j=0}^{n}a_ia_j))

[f(n) = frac{2g(n-1)}{n}+frac{2t(n-1)}{n*n} ]

[g(n)=sum{g(n-1)+a_n}*p=g(n-1)+f(n) ]

(t(n))就比较麻烦了

[t(n)=E(sum_{i=0}^{n}sum_{j=0}^{n}a_ia_j)\ =E(sum_{i=0}^{n-1}sum_{j=0}^{n-1}a_ia_j)+2*E(sum_{i=0}^{n-1}a_i*a_n)+f(n)\ =E(sum_{i=0}^{n-1}sum_{j=0}^{n-1}a_ia_j)+2*sum_{i=1}^{...}(P_i*sum_{i=0}^{n-1}a_i*frac{2*sum_{i=0}^{n-1}a_i}{n})+f(n)(P_i指一种排列的概率)\ =t(n-1)+f(n)+frac{4}{n}E((sum_{i=0}^{n-1}a_i)^2)\ =t(n-1)+frac{4}{n}t(n-1)+f(n)\ ]

NOIP2016换教室<期望DP + 神奇状态?多个状态加一起>

(n)个课程, 可以申请(m)次换教室, 第(i)个课程如果申请后成功则去(d_i), 失败或不申请都是在(c_i), 概率给定
一次性申请, 确定教室后依次走最短路到下一个教室(给图)
问怎样申请期望走的路最短, 输出这个值

Sol:
(f[i][j][0/1])表示到第(i)个教室时申请了(j)次, 这次是否申请, 的最小期望

注意不是是否换教室, 而是是否申请, 因为题目要求一次性申请, 前者可能会有一步一步决策的问题; 而后者是一次选择选不选, 所以是正确的

其实选了的DP值是包含两个状态的, 转移时一起考虑其实跟分开考虑是一样的(画分支想想为什么)

总结

  • 子问题
  • 前缀和优化
  • 递推式-->通向式
  • 式子化简
  • 设置DP的状态, 选择概率/期望
  • 遇到高维的期望应当从高维开始推求出需要哪些低维的期望, 而不是把低维推向高维
  • 严谨写转移方程
原文地址:https://www.cnblogs.com/Kuonji/p/11831840.html