*注意:题面请移步至loj查看。
怎么PKU和THU都编了一些假算法,然后求正确率[汗]。
之前听说PKUWC 2017考了五道dp,看来是真的。[完蛋.jpg]
这三道题,2道概率,1道期望,和佬题组成一样。。。
(我只是把PKUWC 2017在loj后3题做了,是不是全是Day 2就不知道了)
Problem A 随机算法
题目大意
给定一个图。随机一个排列$p_{1}p_2p_3\cdots p_n$。假设当前有一个独立集集合$S$,从小到大枚举$i$,尝试将$p_i$加入$S$中。问得到最大独立集的概率。
每个点有三个状态:被考虑其在独立集中,被考虑且不再独立集中,还未被考虑。
设$f_S$表示,当独立集状态为$S$的概率。
每次我们选择独立集中的点的时候,把新增加的不可能在独立集中的点在排列中的位置也考虑了。
这样一个状态,我们就能表示上面三种点了。
时间复杂度$O(n2^n)$
Code
1 /** 2 * loj 3 * Problem#2540 4 * Accepted 5 * Time: 623ms 6 * Memory: 10876k 7 */ 8 #include <iostream> 9 #include <cstdlib> 10 #include <cstdio> 11 using namespace std; 12 typedef bool boolean; 13 14 const int Mod = 998244353; 15 16 const int N = 20, S = 1 << N; 17 18 int add(int a, int b) { 19 return ((a += b) >= Mod) ? (a - Mod) : (a); 20 } 21 22 int mul(int a, int b) { 23 return a * 1ll * b % Mod; 24 } 25 26 void exgcd(int a, int b, int& x, int& y) { 27 if (!b) 28 x = 1, y = 0; 29 else { 30 exgcd(b, a % b, y, x); 31 y -= (a / b) * x; 32 } 33 } 34 35 int inv(int a, int n) { 36 int x, y; 37 exgcd(a, n, x, y); 38 return (x < 0) ? (x + n) : (x); 39 } 40 41 int n, m; 42 int bit[S]; 43 int g[N], f[S]; 44 boolean indep[S]; 45 int fac[N], _fac[N], adj[S]; 46 47 inline void init() { 48 scanf("%d%d", &n, &m); 49 for (int i = 0, u, v; i < m; i++) { 50 scanf("%d%d", &u, &v); 51 --u, --v; 52 g[u] |= (1 << v); 53 g[v] |= (1 << u); 54 } 55 } 56 57 int permu(int n, int m) { 58 if (n < m) 59 return 0; 60 return mul(fac[n], _fac[n - m]); 61 } 62 63 inline void solve() { 64 int all = 1 << n; 65 indep[0] = true; 66 for (int i = 1; i < all; i++) 67 for (int j = 0; j < n && !indep[i]; j++) 68 if (((i >> j) & 1) && indep[i ^ (1 << j)] && !(g[j] & i)) 69 indep[i] = true; 70 71 for (int i = 1; i < all; i++) 72 bit[i] = bit[i >> 1] + (i & 1); 73 74 int mx = 0; 75 for (int i = 1; i < all; i++) 76 if (indep[i] && bit[i] > mx) 77 mx = bit[i]; 78 79 adj[0] = 0; 80 for (int i = 1; i < all; i++) 81 for (int j = 0; j < n && !adj[i]; j++) 82 if ((i >> j) & 1) 83 adj[i] = adj[i ^ (1 << j)] | g[j]; 84 85 fac[0] = 1; 86 for (int i = 1; i <= n; i++) 87 fac[i] = mul(fac[i - 1], i); 88 _fac[n] = inv(fac[n], Mod); 89 for (int i = n; ~i; i--) 90 _fac[i - 1] = mul(_fac[i], i); 91 92 f[0] = 1; 93 for (int s = 0; s < all - 1; s++) { 94 if (!f[s] || !indep[s]) 95 continue; 96 int ban = adj[s] | s; 97 for (int i = 0; i < n; i++) { 98 if (((ban >> i) & 1)) 99 continue; 100 f[s | (1 << i)] = add(f[s | (1 << i)], mul(f[s], permu(n - bit[ban] - 1, bit[g[i]] - bit[ban & g[i]]))); 101 } 102 } 103 int res = 0; 104 for (int i = 1; i < all; i++) 105 if (indep[i] && bit[i] == mx) 106 res = add(res, f[i]); 107 res = mul(res, _fac[n]); 108 printf("%d\n", res); 109 } 110 111 int main() { 112 init(); 113 solve(); 114 return 0; 115 }