设状态f[i][j]表示有i个a,j个ab的期望
发现如果i+j>=k的话就再来一个b就行了。
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int mod=1e9+6+1; int k,pa,pb,inva,invb,f[1005][1005]; int ksm(int d,int z) { int res=1; while(z) { if(z&1) res=(1ll*res*d)%mod; d=(1ll*d*d)%mod; z>>=1; } return res; } int main() { scanf("%d%d%d",&k,&pa,&pb); int tp=ksm(pa+pb,mod-2); pa=1ll*pa*tp%mod,pb=1ll*pb*tp%mod; invb=ksm(pb,mod-2); for(int i=k;i;i--) { for(int j=k;~j;j--) { if(i+j>=k) {f[i][j]=(1ll*i+1ll*j+1ll*pa*invb)%mod;continue;} f[i][j]=(1ll*f[i+1][j]*pa+1ll*f[i][j+i]*pb)%mod; } } cout<<f[1][0]; return 0; }