日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 人文社科 > 生活经验 >内容正文

生活经验

[树形dp] Jzoj P5233 概率博弈

發(fā)布時(shí)間:2023/11/27 生活经验 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [树形dp] Jzoj P5233 概率博弈 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Description

小A和小B在玩游戲。這個(gè)游戲是這樣的:
有一棵n個(gè)點(diǎn)的以1為根的有根樹,葉子有權(quán)值。假設(shè)有m個(gè)葉子,那么樹上每個(gè)葉子的權(quán)值序列就是一個(gè)1->m 的排列。
一開始在1號(hào)點(diǎn)有一顆棋子。兩人輪流將這顆棋子移向其當(dāng)前位置的一個(gè)兒子。假如棋子到達(dá)葉子,游戲結(jié)束,最終獲得的權(quán)值為所在葉子對(duì)應(yīng)權(quán)值。
小A希望最后的權(quán)值盡量大,小B希望盡量小。小A是先手。
在玩了很多局游戲后,小B對(duì)其中絕大多數(shù)局游戲的結(jié)果不滿意,他覺得是小A對(duì)葉子權(quán)值做了手腳。于是他一怒之下,決定將葉子的權(quán)值隨機(jī)排列。現(xiàn)在小B想知道,假如葉子的權(quán)值是隨機(jī)排列的(即葉子權(quán)值的每種排列都以等概率出現(xiàn)),那么游戲期望的結(jié)果是多少?
請(qǐng)輸出答案乘上m! 對(duì)10^9+7取模的結(jié)果,顯然這是一個(gè)整數(shù)。

Input

輸入文件名為game.in。
第一行包含一個(gè)整數(shù)n。
接下來(lái)n-1行,每行兩個(gè)整數(shù)u,v,表示有一條連接節(jié)點(diǎn)u,v的邊。

Output

輸出文件名為game.out。
輸出一個(gè)整數(shù),表示答案。

Sample Input

輸入1:
5
1 2
2 3
1 4
2 5輸入2:
10
10 7
7 6
10 2
2 3
3 8
3 1
6 9
7 5
1 4

Sample Output

輸出1:
14輸出2:
74

Data Constraint

對(duì)于10%的數(shù)據(jù),n<=5
對(duì)于30%的數(shù)據(jù),n<=10
對(duì)于60%的數(shù)據(jù), n<=50
對(duì)于100%的數(shù)據(jù),n<=5000,保證給出的是一棵合法的樹。

?

題解

  • 我們假設(shè)k為最后取的樹,我們把一個(gè)葉子>=k染成1,把<k的染成0
  • 考慮一下樹形dp,設(shè)f[i][j][0/1]為以i為根的子樹中有j個(gè)1當(dāng)前點(diǎn)為0/1的方案數(shù)
  • 那么對(duì)于當(dāng)前是基層,也就是小A取值,f[i][j][0]= ∏f[son[x]][k][0],f[i][j][1]=。對(duì)于偶層,也就是小B取值也是一樣的
  • 枚舉前面兒子的葉子然后枚舉當(dāng)前要合并的兒子的葉子背包一下
  • 我們可以枚舉k,也就是子樹中1的個(gè)數(shù),所以我們最后要記入答案是∑(f[1][k][1]-f[1][k+1][1])k!?(size[1]-k)!

代碼

 1 #include <cstdio>
 2 #define ll long long
 3 using namespace std;
 4 const ll N=5010,mo=1e9+7;
 5 struct edge { int to,from; }e[N*2];
 6 ll f[N][N][2],head[N],size[N],jc[N],g[N],ans,n,cnt,r;
 7 void insert(int x,int y) { e[++cnt].to=y,e[cnt].from=head[x],head[x]=cnt; }
 8 ll ksm(ll a,ll b){ for (r=1;b;b>>=1,a=a*a%mo) if (b&1) r=r*a%mo; return r;}
 9 ll C(ll x,ll y) { return jc[y]*ksm(jc[y-x],mo-2)%mo*ksm(jc[x],mo-2)%mo; }
10 void dfs(int d,int x,int y,int l,int r)
11 {
12     if (d>g[0]) { (f[x][r][l]+=y)%=mo; return; }
13     for (int i=0;i<=size[g[d]];i++) if (f[g[d]][i][l]) dfs(d+1,x,y*f[g[d]][i][l]%mo,l,r+i);
14 }
15 void dp(int x,int y,int k)
16 {
17     for (int i=head[x];i;i=e[i].from) if (e[i].to!=y) dp(e[i].to,x,k^1),size[x]+=size[e[i].to];
18     g[0]=0; for (int i=head[x];i;i=e[i].from) if (e[i].to!=y) g[++g[0]]=e[i].to;
19     if (size[x])
20     {
21         dfs(1,x,1,k,0);
22         for (int i=0;i<=size[x];i++) f[x][i][k^1]=(C(i,size[x])-f[x][i][k]+mo)%mo;
23     }
24     else size[x]++,f[x][0][0]=f[x][1][1]=1;
25 }
26 int main()
27 {
28     freopen("game.in","r",stdin),freopen("game.out","w",stdout),scanf("%lld",&n);
29     for (int i=1,x,y;i<n;i++) scanf("%d%d",&x,&y),insert(x,y),insert(y,x);
30     jc[0]=1; for (int i=1;i<=n;i++) jc[i]=jc[i-1]*i%mo; dp(1,0,0);
31     for (int i=0;i<=size[1];i++) (ans+=f[1][i][1]*jc[i]%mo*jc[size[1]-i]%mo)%=mo;
32     printf("%lld",ans);
33 }

?

轉(zhuǎn)載于:https://www.cnblogs.com/Comfortable/p/10296073.html

總結(jié)

以上是生活随笔為你收集整理的[树形dp] Jzoj P5233 概率博弈的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。