题目大意:
给定整数k,pa,pb。
初始有一个空序列,每次往末尾添加一个字符,有pa/(pa+pb)的概率添加a,有pb/(pa+pb)的概率添加b。
当ab作为子序列出现了至少k次的时候停止,问此时ab子序列出现次数的期望。对10^9+7取模。
1<=k<=1000,1<=pa,pb<=10^6。
解题思路:
设f[i][j]f[i][j]f[i][j]表示当前有 iii 个a,jjj 个ab子序列到停止时的期望,那么
f[i][j]=papa+pbf[i+1][j]+pbpa+pbf[i][j+i]f[i][j]=\frac{pa}{pa+pb}f[i+1][j]+\frac{pb}{pa+pb}f[i][j+i]f[i][j]=pa+pbpaf[i+1][j]+pa+pbpbf[i][j+i]
其实以上都不是重点,重点在于定下目标状态和终止状态值。
1.目标状态:
如果我们把目标状态定为f[0][0]f[0][0]f[0][0],那么
f[0][0]=(pa∗f[1][0]+pb∗f[0][0])/(pa+pb)f[0][0]=(pa*f[1][0]+pb*f[0][0])/(pa+pb)f[0][0]=(pa∗f[1][0]+pb∗f[0][0])/(pa+pb)会死循环,相当于一开始会有无穷多个b:bbbbb…….bbbbaababa…
但也可推出 f[0][0]=f[1][0]f[0][0]=f[1][0]f[0][0]=f[1][0],所以目标状态应为 f[1][0]f[1][0]f[1][0]。
2.终止状态:
当 i+j≥ki+j\ge ki+j≥k 时,再出现一个b就会停止,所以当 i+j≥ki+j\ge ki+j≥k
f[i][j]=(i+j)B+(i+j+1)AB+(i+j+2)A2B+...f[i][j]=(i+j)B+(i+j+1)AB+(i+j+2)A^2B+...f[i][j]=(i+j)B+(i+j+1)AB+(i+j+2)A2B+...用差比数列的方法计算可得f[i][j]=i+j+papbf[i][j]=i+j+\frac{pa}{pb}f[i][j]=i+j+pbpa
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int getint()
{
int i=0,f=1;char c;
for(c=getchar();(c!='-')&&(c<'0'||c>'9');c=getchar());
if(c=='-')c=getchar(),f=-1;
for(;c>='0'&&c<='9';c=getchar())i=(i<<3)+(i<<1)+c-'0';
return i*f;
}
const int N=1005,mod=1e9+7;
int k;ll pa,pb,inv_pb,f[N][N];
ll Pow(ll x,int y)
{
ll res=1;
for(;y;y>>=1,x=x*x%mod)
if(y&1)res=res*x%mod;
return res;
}
ll dfs(int i,int j)
{
if(i+j>=k)return (i+j+pa*inv_pb)%mod;
if(f[i][j]!=-1)return f[i][j];
return f[i][j]=(dfs(i+1,j)*pa+dfs(i,j+i)*pb)%mod;
}
int main()
{
//freopen("lx.in","r",stdin);
memset(f,-1,sizeof(f));
k=getint(),pa=getint(),pb=getint();
pa=pa*Pow(pa+pb,mod-2)%mod,pb=(1-pa+mod)%mod,inv_pb=Pow(pb,mod-2);
printf("%lld\n",dfs(1,0));
return 0;
}

本文探讨了一种特定的概率序列问题,即在给定概率条件下,求解ab子序列出现k次时的期望次数。通过定义状态转移方程,并利用差比数列方法计算终止状态值,最终得出了解决方案。
310

被折叠的 条评论
为什么被折叠?



