穿越万年的轮回[期望dp]

Posted solemntee

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了穿越万年的轮回[期望dp]相关的知识,希望对你有一定的参考价值。


首先我们设置 d p i , 0 / 1 , 0 / 1 dp_i,0/1,0/1 dpi,0/1,0/1表示经过 i i i次操作之后开头为 r e d / e d r red/edr red/edr,结尾为 r e d / e d r red/edr red/edr的串的期望 r e d red red字符串个数。
然后我们考虑转移:
首先我们要来思考一下期望的本质,这样一个状态,我们以 d p i , 0 , 0 dp_i,0,0 dpi,0,0为例,里面可能有很多种情况,比如串 " r e d r e d " "redred" "redred"和串 " r e d e d r r e d " "rededrred" "rededrred"每一种有一个概率和贡献,假设有 n n n种情况,每一种的概率是 p i p_i pi,贡献是 X i X_i Xi,那么
d p i , 0 , 0 = ∑ i = 1 p i X i dp_i,0,0=\\sum_i=1p_iX_i dpi,0,0=i=1piXi
那么我们考虑在这个状态后面接上一个 " r e d " "red" "red"串,也就是第一种操作,这里面的串的概率和贡献会如何变化呢?
对于上述的一个状态 p i X i p_iX_i piXi,加上一个 " r e d " "red" "red"串之后贡献 X i X_i Xi变为 X i + 1 X_i+1 Xi+1,概率 P i P_i Pi变为 P i 3 \\fracP_i3 3Pi所以这样一种转移让
d p i + 1 , 0 , 0 + = ∑ i = 1 p i 3 ( X i + 1 ) = ∑ i = 1 p i X i 3 + ∑ i = 1 p i 3 dp_i+1,0,0+=\\sum_i=1\\fracp_i 3 (X_i+1)=\\sum_i=1\\fracp_iX_i 3+\\sum_i=1\\fracp_i 3 dpi+1,0,0+=i=13pi(Xi+1)=i=13piXi+i=13pi
所以我们再记录一个 p i , 0 / 1 , 0 / 1 p_i,0/1,0/1 pi,0/1,0/1表示经过 i i i次操作之后开头为 r e d / e d r red/edr red/edr,结尾为 r e d / e d r red/edr red/edr的串的概率,即可转移。
第二种操作和第三种操作同理可以得到:
对于四种情况各自分类讨论即可。但值得注意的是空串不在我们的考虑范围内,得提出来单独计算。

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
const int mod=1e9+7;
ll poww(ll a,ll b)
    ll t=1;
    while(b)
        if(b&1)t=t*a%mod;
        a=a*a%mod;
        b>>=1;
    
    return t;

void add(int &a,int b)
    a+=b;
    if(a>=mod)a-=mod;

void del(int &a,int b)
    a-=b;
    if(a<0)a+=mod;

const int M=2e5+50;
int dp[M][2][2];
int P[M][2][2];

int main()

    int k;
    scanf("%d",&k);
    //P[0][0][0]=1;
    int inv3=poww(3,mod-2);

    int P0=1;
    for(int i=0;i<k;i++)
        //printf("%d %d %d %d\\n",P[i][0][0],P[i][0][1],P[i][1][0],P[i][1][1]);

        
            add(dp[i+1][0][0],1ll*P0*inv3%mod);
            add(P[i+1][0][0],1ll*P0*inv3%mod);

            if(i>=1)
                add(dp[i+1][1][0],1ll*inv3*P0%mod);
                add(P[i+1][1][0],1ll*P0*inv3%mod);

                add(dp[i+1][1][1],1ll*inv3*P0%mod);
                add(P[i+1][1][1],1ll*P0*inv3%mod);

                add(dp[i+1][1][1],1ll*9*inv3%mod*P0%mod);
                add(P[i+1][1][1],1ll*P0*inv3%mod);
            

            P0=1ll*P0*inv3%mod;
        



        // red...red
        add(dp[i+1][0][0],((1ll*dp[i][0][0]*inv3%mod)+1ll*P[i][0][0]*inv3%mod)%mod);
        add(P[i+1][0][0],1ll*P[i][0][0]*inv3%mod);

        add(dp[i+1][0][1],1ll*dp[i][0][0]%mod*inv3%mod);
        add(P[i+1][0][1],1ll*P[i][0][0]*inv3%mod);

        add(dp[i+1][0][0],10ll*dp[i][0][0]%mod*inv3%mod);
        add(P[i+1][0][0],1ll*P[i][0][0]*inv3%mod);



        // red..edr dp[0][1]

        add(dp[i+1][0][0],((1ll*dp[i][0][1]*inv3%mod)+1ll*P[i][0][1]*inv3%mod)%mod);
        add(P[i+1][0][0],1ll*P[i][0][1]*inv3%mod);


        add(dp[i+1][0][1],((1ll*dp[i][0][1]*inv3%mod)+1ll*P[i][0][1]*inv3%mod)%mod);
        add(P[i+1][0][1],1ll*P[i][0][1]*inv3%mod);

        add(dp[i+1][0][1],(1ll*(10ll*dp[i][0][1])%mod*inv3%mod));
        add(P[i+以上是关于穿越万年的轮回[期望dp]的主要内容,如果未能解决你的问题,请参考以下文章

第九集 生死穿越风火山,感受尘世间轮回

中科院打脸谷歌:普通电脑追上量子优越性,几小时搞定原本要一万年的计算...

中科院打脸谷歌:普通电脑追上量子优越性,几小时搞定原本要一万年的计算...

中科院打脸谷歌:普通电脑追上量子优越性,几小时搞定原本要一万年的计算...

Codeforces1097D. Makoto and a Blackboard(数论+dp+概率期望)

HDU 2089 不要62(数位DP)