LuoGu: CF908D New Year and Arbitrary Arrangement
CF: D. New Year and Arbitrary Arrangement
首先要明白题意,一个序列 ab
指 位置存在一个 a
并且 位置存在一个 b
,满足 i < j
的不同二元组 记为一个答案。可以发现,当前序列如果有 个 a
,那么增加一个 b
将会使答案增加 。
考虑 DP , 表示当前有 个 a
,已经有 个答案,满足终止条件后的期望答案。那么有:
考虑边界时,当 时,只需要再有一个 b
即可完成,所以每次有 的期望使答案加 。
即:
但是 转移时会形成环,注意到:
即
所以用 作为起点。
查看代码
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 46 47 48 49 50
| #include <cstdio> using namespace std; typedef long long LL; template <class Type> void read(Type &x) { char c; bool flag = false; while ((c = getchar()) < '0' || c > '9') c == '-' && (flag = true); x = c - '0'; while ((c = getchar()) >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0'; flag && (x = ~x + 1); } template <class Type> void write(Type x) { x < 0 && (putchar('-'), x = ~x + 1); x > 9 && (write(x / 10), 0); putchar(x % 10 + '0'); } const int N = 1e3 + 10, mod = 1e9 + 7; int n, pa, pb, invab, invb, f[N][N]; int binpow (int b, int k = mod - 2) { int res = 1; while (k) { k & 1 && (res = (LL)res * b % mod); b = (LL)b * b % mod; k >>= 1; } return res; } int dfs (int x, int y) { if (x + y >= n) return (x + y + (LL)pa * invb % mod) % mod; if (f[x][y]) return f[x][y]; return f[x][y] = ((LL)dfs(x + 1, y) * pa % mod + (LL)dfs(x, y + x) * pb % mod) * invab % mod; } int main () { read(n), read(pa), read(pb); invab = binpow(pa + pb), invb = binpow(pb); write(dfs(1, 0)); return 0; }
|
Gitalk 加载中 ...