Codeforces908 D. New Year and Arbitrary Arrangement(期望dp)

题意:

在这里插入图片描述
数据范围:k<=1e3,pa,pb<=1e6

解法:

令 d [ i ] [ j ] 表 示 : 当 前 已 经 有 i 个 子 序 列 a b , 还 有 j 个 字 符 a , 到 达 终 点 的 a b 期 望 数 . 令 A 为 添 加 到 a 的 概 率 , 令 b 为 添 加 到 b 的 概 率 . 转 移 方 程 : d [ i ] [ j ] = A ∗ d [ i + 1 ] [ j ] + B ∗ d [ i ] [ i + j ] . 因 为 k < = 1 e 3 , 所 以 : 1. i 的 上 限 设 为 1 e 3 , 即 使 j 不 够 , 下 一 次 选 到 b 马 上 就 满 足 条 件 了 . 2. j 的 上 限 设 为 1 e 3 , 这 个 是 因 为 a b 序 列 数 量 > k 时 就 终 止 了 . 这 样 的 话 状 态 数 就 是 O ( n 2 ) 了 , 开 的 下 . 然 后 考 虑 边 界 数 值 : 当 j < k 但 i + j > = k 时 , 选 出 一 个 b 久 满 足 条 件 了 , 这 时 d [ i ] [ j ] 的 期 望 值 x 为 : x = ∑ a = 0 ∞ B ∗ ( i + j + a ) ∗ A a = B ∗ ∑ a = 0 ∞ ( i + j + a ) ∗ A a A x = B ∗ ∑ a = 0 ∞ ( i + j + a ) ∗ A a + 1 错 位 相 减 得 : ( 1 − A ) x = B ∗ ( i + j ) A 0 + B ∗ ∑ a = 1 ∞ A a = B ∗ ( i + j ) + B ∗ A ∗ ( 1 − A ∞ ) 1 − A 由 于 B = 1 − A , 同 时 ( 1 − A ∞ ) = 1 因 此 式 子 可 以 变 为 : B x = B ∗ ( i + j ) + B ∗ A B x = i + j + A B 记 忆 化 搜 索 即 可 令d[i][j]表示:\\ 当前已经有i个子序列ab,还有j个字符a,到达终点的ab期望数.\\ 令A为添加到a的概率,令b为添加到b的概率.\\ 转移方程:d[i][j]=A*d[i+1][j]+B*d[i][i+j].\\因为k<=1e3,所以:\\ 1.i的上限设为1e3,即使j不够,下一次选到b马上就满足条件了.\\ 2.j的上限设为1e3,这个是因为ab序列数量>k时就终止了.\\ 这样的话状态数就是O(n^2)了,开的下.\\ 然后考虑边界数值:\\ 当j<k但i+j>=k时,选出一个b久满足条件了,\\ 这时d[i][j]的期望值x为:\\ x=\sum_{a=0}^{\infty}B*(i+j+a)*A^{a}\\ =B*\sum_{a=0}^{\infty}(i+j+a)*A^{a}\\ Ax=B*\sum_{a=0}^{\infty}(i+j+a)*A^{a+1}\\ 错位相减得:\\ (1-A)x=B*(i+j)A^0+B*\sum_{a=1}^{\infty}A^{a}\\ =B*(i+j)+B*\frac{A*(1-A^{\infty})}{1-A}\\ 由于B=1-A,同时(1-A^{\infty})=1因此式子可以变为:\\ Bx=B*(i+j)+B*\frac{A}{B}\\ x=i+j+\frac{A}{B}\\ 记忆化搜索即可 d[i][j]:iab,ja,ab.Aa,bb.:d[i][j]=Ad[i+1][j]+Bd[i][i+j].k<=1e3,:1.i1e3,使j,b.2.j1e3,ab>k.O(n2),.:j<ki+j>=k,b,d[i][j]x:x=a=0B(i+j+a)Aa=Ba=0(i+j+a)AaAx=Ba=0(i+j+a)Aa+1:(1A)x=B(i+j)A0+Ba=1Aa=B(i+j)+B1AA(1A)B=1A,(1A)=1:Bx=B(i+j)+BBAx=i+j+BA

code:

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxm=1e3+5;
const int mod=1e9+7;
int d[maxm][maxm];
int k,pa,pb;
int A,B;
int C;
int ppow(int a,int b,int mod){
    
    
    int ans=1%mod;a%=mod;
    while(b){
    
    
        if(b&1)ans=ans*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return ans;
}
int dfs(int i,int j){
    
    
    if(j>=k)return j;
    if(i+j>=k)return i+j+C;
    if(d[i][j]!=-1)return d[i][j];
    return d[i][j]=(A*dfs(i+1,j)%mod+B*dfs(i,i+j)%mod)%mod;
}
signed main(){
    
    
    ios::sync_with_stdio(0);
    cin>>k>>pa>>pb;
    A=pa*ppow(pa+pb,mod-2,mod)%mod;
    B=pb*ppow(pa+pb,mod-2,mod)%mod;
    C=pa*ppow(pb,mod-2,mod)%mod;
    memset(d,-1,sizeof d);
    cout<<dfs(1,0)<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_44178736/article/details/112794007