• [CF908D]New Year and Arbitrary Arrangement


    题面在这里

    题意

    给定三个数(k,pa,pb),每次有(frac{pa}{pa+pb})的概率往后面添加一个'(a)',每次有(frac{pb}{pa+pb})的概率往后面添加一个'(b)'当出现了(k)个形如'(ab)'的子序列(不用连续)时停止。求最后的形如'(ab)'的子序列个数的期望。答案对(1e9+7)取模。
    (kleq 1000)

    sol

    一看到(kleq 1000)马上想到(f[i][j])表示已经有(i)(a),目前'(ab)'的子序列的个数为(j)的期望
    转移:$$f[i][j]=f[i][j]+frac{pa}{pa+pb}*f[i+1][j]+frac{pb}{pa+pb}f[i][i+j]$$
    但是需要考虑(bbb...bbab)(前面无限个'b')和(abbaaa...)(后面无限个'a')的情况
    首先前面的'(b)'不管有多少都不需要考虑
    然后考虑的就是后面无限个'a'的情况
    我们注意到,如果状态(f[i][j])中的(i+jgeq k),那么只需要再加上一个'(b)'统计就会结束
    那么(f[i][j])的求解实际上就是在解一个无穷级数:

    [f[i][j]=frac{pb}{pa+pb}(i+j)+frac{pa}{pa+pb} imesfrac{pb}{pa+pb}(i+j+1)+(frac{pa}{pa+pb})^{2} imesfrac{pb}{pa+pb}(i+j+2)+... ]

    可以化简成

    [f[i][j]=i+j+frac{pa}{pb} ]

    那么对于(i+jgeq k)的情况直接算出答案,其余的情况递推求解就好

    代码

    #include<bits/stdc++.h>
    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<iomanip>
    #include<cstring>
    #include<complex>
    #include<vector>
    #include<cstdio>
    #include<string>
    #include<bitset>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<map>
    #include<set>
    #define mp make_pair
    #define pb push_back
    #define RG register
    #define il inline
    using namespace std;
    typedef unsigned long long ull;
    typedef vector<int>VI;
    typedef long long ll;
    typedef double dd;
    const dd eps=1e-10;
    const int mod=1e9+7;
    const int N=1010;
    const int M=90000;
    il ll read(){
        RG ll data=0,w=1;RG char ch=getchar();
        while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
        if(ch=='-')w=-1,ch=getchar();
        while(ch<='9'&&ch>='0')data=data*10+ch-48,ch=getchar();
        return data*w;
    }
    
    il void file(){
        //freopen("a.in","r",stdin);
        //freopen("a.out","w",stdout);
    }
    
    il ll poww(ll a,ll b){RG ll ret=1;for(a%=mod;b;b>>=1,a=a*a%mod)
                                                                            if(b&1)ret=ret*a%mod;return ret;}
    
    int k,pa,pb,rev,revb,f[N][N];
    il int search(int x,int y){
        if(f[x][y])return f[x][y];
        if(x+y>=k)return f[x][y]=(x+y+1ll*pa*revb%mod)%mod;
        return f[x][y]=(1ll*pa*rev%mod*search(x+1,y)%mod+1ll*pb*rev%mod*search(x,x+y)%mod)%mod;
    }
    
    int main()
    {
        k=read();pa=read();pb=read();
        rev=poww(pa+pb,mod-2);revb=poww(pb,mod-2);
        printf("%d
    ",search(1,0));
        return 0;
    }
    
    
  • 相关阅读:
    spark 随意笔记
    c#读取输入字符串,从数据源中查找以该字符串开头的所有字符串(使用正则表达式)
    我的收藏链接地址
    SQL查询时,遇到用到关键词作的字段。将该字段用一对中括号括起来[]
    SQL数据类型相互转换
    Javascript获取系统当前时间
    节点类型nodeType的取值
    混合布局编程挑战
    Webstorm破解方法
    二列布局
  • 原文地址:https://www.cnblogs.com/cjfdf/p/8437045.html
Copyright © 2020-2023  润新知