zoukankan      html  css  js  c++  java
  • CF908D New Year and Arbitrary Arrangement

    题意

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

    Sol

    (f[i][j])表示前面有(i)(a)(j)(ab)的期望(ab)的对数
    倒着来转移
    显然
    (f[i][j]=f[i+1][j]*frac{pa}{pa+pb}+f[i][i+j]*frac{pb}{pa+pb})
    答案就是(f[0][0])
    然而(f[0][0]=f[1][0]*frac{pa}{pa+pb}+f[0][0]*frac{pb}{pa+pb})
    不好算
    移项后得到(f[0][0]=f[1][0])
    所以输出(f[1][0])就好了

    然而串长是无限的,(a)的个数也是无限的,(ab)的对数无限,它们可以到(infty)
    这就很不好做了了

    但是你会发现,当(a)无穷多时,放一个(b)(ab)对数就会超过(k),显然直接就停了
    对于(f[i][j]),当(i+j>=k)时,考虑它的期望
    也就是(f[i][j]=frac{pb}{pa+pb}sum_{l=0}^{infty}(frac{pa}{pa+pb})^l(i+j+l))

    (S=sum_{l=0}^{infty}(frac{pa}{pa+pb})^l(i+j+l))

    (frac{pa}{pa+pb}S=sum_{l=0}^{infty}(frac{pa}{pa+pb})^{l+1}(i+j+l))
    两式相减得
    ((1-frac{pa}{pa+pb})S=(i+j)+sum_{l=1}^{infty}(frac{pa}{pa+pb})^l)

    (sum_{l=1}^{infty}(frac{pa}{pa+pb})^l)
    也可以类似处理
    得到就是
    (frac{frac{pa}{pa+pb}-(frac{pa}{pa+pb})^{infty}}{1-frac{pa}{pa+pb}}=frac{pa}{pb})
    带回去
    ((1-frac{pa}{pa+pb})S=(i+j)+frac{pa}{pb})

    (frac{pb}{pa+pb}S=(i+j)+frac{pa}{pb})

    所以
    (f[i][j]=frac{pb}{pa+pb}S=(i+j)+frac{pa}{pb})

    # include <bits/stdc++.h>
    # define RG register
    # define IL inline
    # define Fill(a, b) memset(a, b, sizeof(a))
    using namespace std;
    typedef long long ll;
    const int Zsy(1e9 + 7);
    
    int k, pa, pb, invb, inv, f[1005][1005], Pa, Pb;
    
    IL int Input(){
        RG int x = 0, z = 1; RG char c = getchar();
        for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
        for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
        return x * z;
    }
    
    IL int Pow(RG ll x, RG ll y){
    	RG ll ret = 1;
    	for(; y; y >>= 1, x = x * x % Zsy)
    		if(y & 1) ret = ret * x % Zsy;
    	return ret;
    }
    
    int main(RG int argc, RG char *argv[]){
    	k = Input(), pa = Input(), pb = Input();
    	invb = Pow(pb, Zsy - 2), inv = Pow(pa + pb, Zsy - 2);
    	Pa = 1LL * pa * inv % Zsy, Pb = 1LL * pb * inv % Zsy;
    	for(RG int i = k; i; --i)
    		for(RG int j = k; ~j; --j)
    			if(i + j >= k) f[i][j] = ((i + j) + 1LL * pa * invb % Zsy + Zsy) % Zsy;
    			else f[i][j] = (1LL * f[i + 1][j] * Pa % Zsy + 1LL * f[i][j + i] * Pb % Zsy) % Zsy;
    	printf("%d
    ", f[1][0]);
        return 0;
    }
    
    
  • 相关阅读:
    IDEA操作git的一些常用技巧
    实现多Realm时,可能会出现的问题
    Solr入门-Solr服务安装(windows系统)
    ES6中的Set和Map集合
    ES6中的类
    ES6数组扩展
    ES6定型数组
    Promise和异步编程
    深入理解ajax系列第八篇
    深入理解ajax系列第六篇
  • 原文地址:https://www.cnblogs.com/cjoieryl/p/8671969.html
Copyright © 2011-2022 走看看