CF1556F-Sports Betting【状压dp,数学期望】
正題
題目鏈接:https://www.luogu.com.cn/problem/CF1556F
題目大意
nnn個點的一張競賽圖,每個點有一個權值aia_iai?,(i,j)(i,j)(i,j)之間的邊iii連jjj的概率是aiai+aj\frac{a_i}{a_i+a_j}ai?+aj?ai??,否則jjj連iii。
現在期望有多少個點能走到全圖的任意一個點。
1≤n≤14,1≤ai≤1061\leq n\leq 14,1\leq a_i\leq 10^61≤n≤14,1≤ai?≤106
解題思路
考慮狀壓dpdpdp,首先枚舉起點ppp,設fSf_{S}fS?表示目前只考慮了點集SSS且ppp都能到達。
那么對于點集SSS是任意一張圖的概率是111,然后考慮枚舉一個ppp能到達的集合TTT之后其他點ppp都不能到達,為了方便表示下面記gS,Tg_{S,T}gS,T?表示點集SSS和TTT之間的邊都是SSS指向TTT的概率那么有
1=∑T?SfT×gS?T,T1=\sum_{T\subseteq S}f_T\times g_{S-T,T}1=T?S∑?fT?×gS?T,T?
?fS=1?∑T?SfT×gS?T,T\Rightarrow f_S=1-\sum_{T\subset S}f_T\times g_{S-T,T}?fS?=1?T?S∑?fT?×gS?T,T?
考慮如何預處理gS,Tg_{S,T}gS,T?,不難發現因為S∩T=?S\cap T=\varnothingS∩T=?所以這個狀態數是3n3^n3n的我們可以用三進制狀壓,不過得先預處理rp,Sr_{p,S}rp,S?表示ppp與集合SSS之間的邊都是ppp連向SSS的概率。
時間復雜度:O(3nn+2nn2)O(3^nn+2^nn^2)O(3nn+2nn2)
code
#include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; const ll N=14,M=2e6+10,P=1e9+7; ll n,ans,inv[M],pw[N+1],a[N],r[N][1<<N],tr[1<<N],f[1<<N],g[4782969]; signed main() {inv[1]=1;for(ll i=2;i<M;i++)inv[i]=P-(P/i)*inv[P%i]%P;scanf("%lld",&n);for(ll i=0;i<n;i++)scanf("%lld",&a[i]);ll MS=(1<<n);for(ll p=0;p<n;p++){r[p][0]=1;for(ll s=0;s<MS;s++){if((s>>p)&1)continue;for(ll i=0;i<n;i++)if((s>>i)&1){r[p][s]=r[p][s^(1<<i)]*a[p]%P*inv[a[p]+a[i]]%P;break;}}}pw[0]=1;for(ll i=1;i<=n;i++)pw[i]=pw[i-1]*3;for(ll s=1;s<MS;s++)for(ll i=0;i<n;i++)if((s>>i)&1)tr[s]=tr[s^(1<<i)]+pw[i];for(ll s=0;s<pw[n];s++)g[s]=1;for(ll s=0;s<MS;s++)for(ll i=0;i<n;i++){if(!((s>>i)&1))continue;for(ll t=s;t;t=(t-1)&s){if((t>>i)&1)continue;(g[tr[s]+tr[t]]*=r[i][t])%=P;}}for(ll p=0;p<n;p++){memset(f,0,sizeof(f));for(ll s=0;s<MS;s++){if(!((s>>p)&1))continue;f[s]=1;for(ll t=(s-1)&s;t;t=(t-1)&s){if(!((t>>p)&1))continue;(f[s]+=P-f[t]*g[tr[s]+tr[t]]%P)%=P;}}(ans+=f[MS-1])%=P;}printf("%lld\n",ans);return 0; } 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的CF1556F-Sports Betting【状压dp,数学期望】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 机不可失时不再来的意思 指的是什么含义
- 下一篇: 四字qq昵称 甜美可爱的四字网名