记 $min{S}$ 为集合 $S$ 中最小值,$max{S}$ 为集合 $S$ 中最大值
则有 $max{S}=sumlimits_{T subseteq S,T eq emptyset}(-1)^{|T|-1}min{T}$
这个东西可以用来求“全都出现的期望时间”
hdu4336 Card Collector
有 n 种卡片,每秒你有 $P_i$ 的概率获得第 $i$ 张卡片,求获得所有卡片至少一张的期望时间
$n leq 20$
sol:
直接套上面那个式子,令 $max{S}$ 为得到 $S$ 集合中最晚的一张的期望时间,易得这也是得到 $S$ 集合的期望时间
然后套一下式子,就只用对于 $S$ 的每一个子集 $T$ ,计算出至少得到一个 $T$ 中元素的期望时间
易得 $min{T}=frac{1}{sumlimits_{i in T}P_i}$
然后就做完了
#include<bits/stdc++.h> #define LL long long using namespace std; inline int read() { int x = 0,f = 1;char ch = getchar(); for(;!isdigit(ch);ch = getchar())if(ch == '-') f = -f; for(;isdigit(ch);ch = getchar())x = 10 * x + ch - '0'; return x * f; } int n;double p[25],ans; void dfs(int x,double e,int opt) { if(x > n) { if(e > 1e-7)ans += opt / e; return; } dfs(x + 1,e,opt); dfs(x + 1,e + p[x],-opt); } int main() { while(scanf("%d",&n) != EOF) { for(int i=1;i<=n;i++)cin >> p[i]; ans = 0;dfs(1,0,-1); printf("%.6lf ",ans); } }
PKUWC2018 随机游走
一棵树,你从 $x$ 出发随机走,$q$ 次询问,每次给定一个点集 $S$,求走完 $S$ 的期望时间
$n leq 18,q leq 5000$
sol:
根据上一题的套路,我们要求对于每个子集 $T$,至少走到 $T$ 中的一个点的期望步数
然后根据不知道在哪(???)知道的套路,树上期望题可以记 $f_{(x,S)}$ 表示从 $x$ 开始走,第一次走到 $S$ 中的一个元素的期望步数
考虑这个 $f_{(x,S)}$ 怎么推,如果 $x in S$,则 $f_{(x,S)} = 0$,如果不是的话,$f_{(x,S)} = frac{1}{d_x} imes sum f_{(y,S)} + 1$
然后发现 $f_{(x,S)}=a_x imes f_{(fa_x,S)} + b_x$ ,从 $0$ 的点向上推出每个 $a,b$ 即可
#include<bits/stdc++.h> #define LL long long using namespace std; inline int read() { int x = 0,f = 1;char ch = getchar(); for(;!isdigit(ch);ch = getchar())if(ch == '-') f = -f; for(;isdigit(ch);ch = getchar())x = 10 * x + ch - '0'; return x * f; } const int mod = 998244353,maxn = (1 << 20); int n,q,x,d[maxn],f[maxn],k[maxn],b[maxn],fa[maxn]; vector<int> G[30]; inline int ksm(int x,int t) { int res = 1; while(t) { if(t & 1) res = 1LL * res * x % mod; x = 1LL * x * x % mod; t = t >> 1; }return res; } inline void dfs(int x,int S) { if(S & (1 << (x - 1))) { k[x] = b[x] = 0; return; } k[x] = b[x] = d[x]; for(auto to : G[x]) { if(to == fa[x])continue; fa[to] = x;dfs(to,S); k[x] = (mod - k[to] + k[x]) % mod; b[x] = (b[to] + b[x]) % mod; } k[x] = ksm(k[x],mod - 2); b[x] = 1LL * b[x] * k[x] % mod; } int main() { n = read();q = read();x = read(); for(int i=2;i<=n;i++) { int u = read(),v = read(); G[u].push_back(v);d[u]++; G[v].push_back(u);d[v]++; } for(int S=1;S<(1 << n);S++) { dfs(x,S); f[S] = b[x]; } while(q--) { int nq = read(),S = 0; for(int i=1;i<=nq;i++)S = S | (1 << (read() - 1)); LL ans = 0; for(int ps=S;ps;ps=(ps-1)&S) { int cnt = __builtin_popcount(ps); ans = (ans + ((cnt & 1) ? 1 : -1) * f[ps] + mod) % mod; }cout<<ans<<endl; } }