• CF908D New Year and Arbitrary Arrangement


    LXII.CF908D New Year and Arbitrary Arrangement

    思路:

    期望题果然还是恶心呀……

    我们设\(f[i][j]\)表示当串中有\(i\)a\(j\)ab时的方案数。为了方便,设\(A=\dfrac{P_a}{P_a+P_b},B=\dfrac{P_b}{P_a+P_b}\)

    显然,可以这样转移:

    \(f[i][j]=f[i+1][j]*A+f[i][i+j]*B\)

    因为,如果串后面加上一个a,概率是\(A\),并且加完后唯一的影响就是\(i+1\);如果加入一个b,概率是\(B\),加完后前面每一个a都会与这个b形成一对ab

    那么边界条件呢?

    显然,当\(i+j\geq k\)时,只要再往后面加入一个b,过程就停止了。

    则这个的期望长度应该是:

    \(B*\sum\limits_{a=0}^{\infty}(i+j+a)*A^a\)

    其中,枚举的这个\(a\)是在终于搞出一个b前,所刷出的a的数量。

    为了方便,我们设\(i+j=c\),并用\(i\)替换\(a\)。即:

    \(B*\sum\limits_{i=0}^{\infty}(c+i)*A^i\)

    因为\(A+B=1\),我们可以用\((1-A)\)\(B\)

    即:

    \((1-A)*\sum\limits_{i=0}^{\infty}(c+i)*A^i\)

    拆开括号得

    \(\sum\limits_{i=0}^{\infty}(c+i)*A^i-\sum\limits_{i=0}^{\infty}(c+i)*A^{i+1}\)

    一上来直接\(\infty\)有些不直观,我们用\(n\)替换掉。

    \(\sum\limits_{i=0}^n(c+i)*A^i-\sum\limits_{i=0}^n(c+i)*A^{i+1}\)

    在第二个式子里面用\(i+1\)代掉\(i\)

    \(\sum\limits_{i=0}^n(c+i)*A^i-\sum\limits_{i=1}^{n+1}(c+i-1)*A^i\)

    将第一个\(\Sigma\)\(i=0\)的情况和第二个\(\Sigma\)\(i=n+1\)的情况分别提出

    \(c+\sum\limits_{i=1}^n(c+i)*A^i-\sum\limits_{i=1}^n(c+i-1)*A^i-(c+n)*A^{n+1}\)

    合并两个\(\Sigma\)

    \(c+\sum\limits_{i=1}^nA^i-(c+n)*A^{n+1}\)

    套等比数列求和公式(注意要先提出一个\(A\)使首项为\(1\)

    \(c+A*\dfrac{1-A^n}{1-A}-(c+n)*A^{n+1}\)

    注意到\(1-A=B\)

    \(c+A*\dfrac{1-A^n}{B}-(c+n)*A^{n+1}\)

    现在,考虑\(n\rightarrow\infty\)的情况。即:

    \(\lim\limits_{n\rightarrow\infty}c+A*\dfrac{1-A^n}{B}-(c+n)*A^{n+1}\)

    注意到\(0<A<1\),因此\(\lim\limits_{n\rightarrow\infty}A^n=0\)

    带入发现

    \(c+A*\dfrac{1-0}{B}-(c+n)*0\)

    处理一下

    \(c+\dfrac{A}{B}\)

    注意到我们一开始的定义了吗?

    \(A=\dfrac{P_a}{P_a+P_b},B=\dfrac{P_b}{P_a+P_b}\)

    以及\(c=i+j\)

    代入得

    \(i+j+\dfrac{P_a}{P_b}\)

    也就是说,边界条件就是\(f[i][j]=i+j+\dfrac{P_a}{P_b}(i+j\geq k)\)!!!

    再搬出我们一开始的转移式

    \(f[i][j]=f[i+1][j]*A+f[i][i+j]*B\)

    完事。

    哦,另外,还要思考一下答案到底是\(f[0][0]\)还是\(f[1][0]\)

    因为一开始的那些b,无论来多少个都是没用的,因此不如直接从\(f[1][0]\)开始。(事实上,你如果把转移式代回去或者打个表的话,你会发现就有\(f[0][0]=f[1][0]\)

    复杂度\(O(k^2+\log mod)\)

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    int n,a,b,A,B,f[1010][1010],c;
    const int mod=1e9+7;
    int ksm(int x,int y){
        int z=1;
        for(;y;x=(1ll*x*x)%mod,y>>=1)if(y&1)z=(1ll*z*x)%mod;
        return z;
    }
    int dfs(int x,int y){
        if(x+y>=n)return x+y+c;
        if(f[x][y]!=-1)return f[x][y];
        int &res=f[x][y];res=0;
        (res+=1ll*dfs(x+1,y)*A%mod)%=mod;
        (res+=1ll*dfs(x,x+y)*B%mod)%=mod;
        return res;
    }
    int main(){
        scanf("%d%d%d",&n,&a,&b),A=1ll*a*ksm(a+b,mod-2)%mod,B=1ll*b*ksm(a+b,mod-2)%mod,c=1ll*a*ksm(b,mod-2)%mod,memset(f,-1,sizeof(f));
        printf("%d\n",dfs(1,0));
        return 0;
    }
    

  • 相关阅读:
    git版本控制工具的使用(2)
    如何才能够系统地学习Java并发技术?
    Java集合类常见面试知识点总结
    想了解Java后端学习路线?你只需要这一张图!
    你不可错过的Java学习资源清单
    Java后端工程师必备书单(从Java基础到分布式)
    Java工程师修炼之路(校招总结)
    ​为什么我会选择走 Java 这条路?
    从Java小白到收获BAT等offer,分享我这两年的经验和感悟
    从零基础到拿到网易Java实习offer,我做对了哪些事
  • 原文地址:https://www.cnblogs.com/Troverld/p/14597525.html
Copyright © 2020-2023  润新知