题目大意

题意

分析

考虑 f[i][j]f[i][j] 表示 有 iiaajj 个匹配的 abab 的期望

容易想到转移

f[i][j]=pa/(pa+pb)f[i+1][j]+pb/(pa+pb)f[i][j+i]f[i][j] = pa/(pa+pb)* f[i+1][j] + pb/(pa+pb)*f[i][j+i]

因为单独一个 bb 无法对 abab 产生贡献,所以最后的答案是 f[1][0]f[1][0]

现在要考虑 如果前面都是 aa 的情况要如何处理

如果当 i+j>=ki+j >= k 时,只要再放一个 bb 就可以了

那么就是在考虑第一次放 bb 后的子序列 abab 期望个数

推导

推导

因为不好确定dpdp方向,所以进行记忆化搜索

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
const int mod = 1e9+7;
template<int T>
struct ModInt {
const static int MD = 1e9+7;
int x;
ModInt(ll x = 0) : x(x % MD) {}
int get() { return x; }
ModInt operator + (const ModInt &that) const { int x0 = x + that.x; return ModInt(x0 < MD ? x0 : x0 - MD); }
ModInt operator - (const ModInt &that) const { int x0 = x - that.x; return ModInt(x0 < MD ? x0 + MD : x0); }
ModInt operator * (const ModInt &that) const { return ModInt((long long)x * that.x % MD); }
ModInt operator / (const ModInt &that) const { return *this * that.inverse(); }
void operator += (const ModInt &that) { x += that.x; if (x >= MD) x -= MD; }
void operator -= (const ModInt &that) { x -= that.x; if (x < 0) x += MD; }
void operator *= (const ModInt &that) { x = (long long)x * that.x % MD; }
void operator /= (const ModInt &that) { *this = *this / that; }
ModInt inverse() const {
int a = x, b = MD, u = 1, v = 0;
while (b) {
int t = a / b;
a -= t * b; std::swap(a, b);
u -= t * v; std::swap(u, v);
}
if (u < 0) u += MD;
return u;
}
};
typedef ModInt<mod> mint;
mint pa,pb;
int k;

bool st[1005][1005];
mint f[1005][1005];

mint dfs(int i,int j){
if(st[i][j]) return f[i][j];
st[i][j] = 1;
if(i+j >= k) return f[i][j] = (pa/pb+i+j);
return f[i][j] = (pa/(pa+pb))*dfs(i+1,j) + (pb/(pa+pb))*dfs(i,j+i);
}
signed main()
{
cin >> k >> pa.x >> pb.x;
cout << dfs(1,0).get() << endl;
return 0;
}

mint 板子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
template<int T>
struct ModInt {
const static int MD = 1e9+7;
int x;
ModInt(ll x = 0) : x(x % MD) {}
int get() { return x; }
ModInt operator + (const ModInt &that) const { int x0 = x + that.x; return ModInt(x0 < MD ? x0 : x0 - MD); }
ModInt operator - (const ModInt &that) const { int x0 = x - that.x; return ModInt(x0 < MD ? x0 + MD : x0); }
ModInt operator * (const ModInt &that) const { return ModInt((long long)x * that.x % MD); }
ModInt operator / (const ModInt &that) const { return *this * that.inverse(); }
void operator += (const ModInt &that) { x += that.x; if (x >= MD) x -= MD; }
void operator -= (const ModInt &that) { x -= that.x; if (x < 0) x += MD; }
void operator *= (const ModInt &that) { x = (long long)x * that.x % MD; }
void operator /= (const ModInt &that) { *this = *this / that; }
ModInt inverse() const {
int a = x, b = MD, u = 1, v = 0;
while (b) {
int t = a / b;
a -= t * b; std::swap(a, b);
u -= t * v; std::swap(u, v);
}
if (u < 0) u += MD;
return u;
}
};
typedef ModInt<mod> mint;

学习资料