D New Year and Arbitrary Arrangement
题意:
输入
k
(
1
e
3
)
,
p
a
,
p
b
k(1e3),pa,pb
k(1e3),pa,pb;
初始是空串,每次有
p
a
/
(
p
a
+
p
b
)
pa/(pa+pb)
pa/(pa+pb)的概率在串尾加
a
a
a,
p
b
/
(
p
a
+
p
b
)
pb/(pa+pb)
pb/(pa+pb)的概率在串尾加
b
b
b,当串中子串(位置不一定相邻)为
a
b
ab
ab的个数大于等于
k
k
k时,结束。问结束是
a
b
ab
ab个数期望是多少。
题解:
设
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j]为当前
a
a
a的个数为
i
i
i,
a
b
ab
ab的个数为
j
j
j,到结束时
a
b
ab
ab个数的期望。
转移:
d
p
[
i
]
[
j
]
=
(
p
a
∗
d
p
[
i
+
1
]
[
j
]
+
p
b
∗
d
p
[
i
]
[
i
+
j
]
)
/
(
p
a
+
p
b
)
dp[i][j]=(pa*dp[i+1][j]+pb*dp[i][i+j])/(pa+pb)
dp[i][j]=(pa∗dp[i+1][j]+pb∗dp[i][i+j])/(pa+pb)
当
i
+
j
>
=
k
i+j>=k
i+j>=k时,通过错位相减可以算出:
d
p
[
i
]
[
j
]
=
i
+
j
+
p
a
/
p
b
dp[i][j]=i+j+pa/pb
dp[i][j]=i+j+pa/pb;
最后
d
p
[
1
]
[
0
]
dp[1][0]
dp[1][0]即为所求。
代码:
#include<bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
int k,pa,pb;
int dp[1009][1009];
int poww(int a,int b,int c){
int ans=1,base=a;
while(b){
if(b&1)ans=1ll*ans*base%c;
base=1ll*base*base%c;
b>>=1;
}
return ans;
}
int main(){
// freopen("tt.in","r",stdin),freopen("tt.out","w",stdout);
cin>>k>>pa>>pb;
int inva=poww(pa,mod-2,mod),invb=poww(pb,mod-2,mod),invc=poww(pa+pb,mod-2,mod);
for(int i=k;i>=1;i--)
for(int j=k;j>=0;j--)
if(i+j>=k)dp[i][j]=(i+j+1ll*pa*invb)%mod;
else dp[i][j]=(1ll*pa*invc%mod*dp[i+1][j]+1ll*pb*invc%mod*dp[i][i+j])%mod;
cout<<dp[1][0]<<endl;
return 0;
}