题面

小A和小B在玩游戏。这个游戏是这样的:

有一棵n个点的以1为根的有根树,叶子有权值。假设有m个叶子,那么树上每个叶子的权值序列就是一个1->m 的排列。

一开始在1号点有一颗棋子。两人轮流将这颗棋子移向其当前位置的一个儿子。假如棋子到达叶子,游戏结束,最终获得的权值为所在叶子对应权值。

小A希望最后的权值尽量大,小B希望尽量小。小A是先手。

在玩了很多局游戏后,小B对其中绝大多数局游戏的结果不满意,他觉得是小A对叶子权值做了手脚。于是他一怒之下,决定将叶子的权值随机排列。现在小B想知道,假如叶子的权值是随机排列的(即叶子权值的每种排列都以等概率出现),那么游戏期望的结果是多少?

请输出答案乘上m! 对10^9+7取模的结果,显然这是一个整数。

对于100%的数据,n<=5000,保证给出的是一棵合法的树。

100

首先预处理一个dp,\(f[i][j][0/1]\)表示以第i个结点为子树,填了j个0到叶子结点中,并且结点i的值为0/1,的方案数。

这个可以用树形背包弄出来,注意奇偶性。

然后就能统计答案了。

\[Ans=\sum_{i=1}^n f[1][i][1]*i!*(sum-i)!
\]

Code

#include<bits/stdc++.h>
#define ll long long
#define fo(i,x,y) for(int i=x;i<=y;i++)
#define fd(i,x,y) for(int i=x;i>=y;i--)
using namespace std;
const char* fin="game.in";
const char* fout="game.out";
const int inf=0x7fffffff;
int read(){
int x=0;
char ch=getchar();
while (ch<'0' || ch>'9') ch=getchar();
while (ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
return x;
}
const int maxn=5007,maxm=maxn*2,mo=1000000007;
int n,fi[maxn],la[maxm],ne[maxm],tot,ans,fact[maxn];
int w[maxn],f[maxn][maxn][2],g[maxn][maxn][2];
void add_line(int a,int b){
tot++;
ne[tot]=fi[a];
la[tot]=b;
fi[a]=tot;
}
int getw(int v,int from){
w[v]=0;
for(int k=fi[v];k;k=ne[k])
if (la[k]!=from)
w[v]+=getw(la[k],v);
return (w[v]?w[v]:w[v]=1);
}
void dfs(int v,int from,int x){
bool az=true;
for(int k=fi[v];k;k=ne[k])
if (la[k]!=from){
dfs(la[k],v,x^1);
if (az) memcpy(f[v],f[la[k]],sizeof f[v]),az=false;
else{
fo(i,0,w[v]) g[v][i][0]=0,g[v][i][1]=0;
fo(j,0,w[la[k]])
fd(i,w[v],0){
if (i+j>w[v]) continue;
if (x==0){
g[v][i+j][0]=(g[v][i+j][0]+1ll*f[v][i][0]*f[la[k]][j][1])%mo;
g[v][i+j][0]=(g[v][i+j][0]+1ll*f[v][i][1]*f[la[k]][j][0])%mo;
g[v][i+j][0]=(g[v][i+j][0]+1ll*f[v][i][0]*f[la[k]][j][0])%mo;
g[v][i+j][1]=(g[v][i+j][1]+1ll*f[v][i][1]*f[la[k]][j][1])%mo;
}else{
g[v][i+j][1]=(g[v][i+j][1]+1ll*f[v][i][0]*f[la[k]][j][1])%mo;
g[v][i+j][1]=(g[v][i+j][1]+1ll*f[v][i][1]*f[la[k]][j][0])%mo;
g[v][i+j][1]=(g[v][i+j][1]+1ll*f[v][i][1]*f[la[k]][j][1])%mo;
g[v][i+j][0]=(g[v][i+j][0]+1ll*f[v][i][0]*f[la[k]][j][0])%mo;
}
}
fo(i,0,w[v]) f[v][i][0]=g[v][i][0],f[v][i][1]=g[v][i][1];
}
}
if (az){
f[v][0][1]=1;
f[v][1][0]=1;
}
}
int main(){
freopen(fin,"r",stdin);
freopen(fout,"w",stdout);
scanf("%d",&n);
if (n==1){
printf("1");
return 0;
}
fo(i,1,n-1){
int j,k;
scanf("%d%d",&j,&k);
add_line(j,k);
add_line(k,j);
}
fact[0]=1;
fo(i,1,n) fact[i]=1ll*fact[i-1]*i%mo;
getw(1,0);
dfs(1,0,1);
fo(i,0,w[1]) ans=(ans+1ll*f[1][i][1]*fact[i]%mo*fact[w[1]-i]%mo)%mo;
ans=(ans+mo)%mo;
printf("%d",ans);
return 0;
}

【JZOJ5233】【GDOI模拟8.5】概率博弈 树形dp+期望的更多相关文章

  1. [CF697D]Puzzles 树形dp/期望dp

    Problem Puzzles 题目大意 给一棵树,dfs时随机等概率选择走子树,求期望时间戳. Solution 一个非常简单的树形dp?期望dp.推导出来转移式就非常简单了. 在经过分析以后,我们 ...

  2. BZOJ 3566: [SHOI2014]概率充电器 [树形DP 概率]

    3566: [SHOI2014]概率充电器 题意:一棵树,每个点\(q[i]\)的概率直接充电,每条边\(p[i]\)的概率导电,电可以沿边传递使其他点间接充电.求进入充电状态的点期望个数 糖教题解传 ...

  3. Codeforces 123E Maze(树形DP+期望)

    [题目链接] http://codeforces.com/problemset/problem/123/E [题目大意] 给出一棵,给出从每个点出发的概率和以每个点为终点的概率,求出每次按照dfs序从 ...

  4. BZOJ2878 [Noi2012]迷失游乐园 【基环树 + 树形dp + 期望dp】

    题目链接 BZOJ2878 题解 除了实现起来比较长,思维难度还是挺小的 观察数据范围发现环长不超过\(20\),而我们去掉环上任何一个点就可以形成森林 于是乎我们枚举断掉的点,然后只需求出剩余每个点 ...

  5. CF839 C 树形DP 期望

    给一颗树,求从根出发路径长度的期望是多少. 树形DP 要想清楚期望的计算 /** @Date : 2017-08-12 23:09:41 * @FileName: C.cpp * @Platform: ...

  6. Codeforces 804D Expected diameter of a tree(树形DP+期望)

    [题目链接] http://codeforces.com/contest/804/problem/D [题目大意] 给你一个森林,每次询问给出u,v, 从u所在连通块中随机选出一个点与v所在连通块中随 ...

  7. BZOJ 3566: [SHOI2014]概率充电器( 树形dp )

    通过一次dfs求出dp(x)表示节点x考虑了x和x的子树都没成功充电的概率, dp(x) = (1-p[x])π(1 - (1-dp[son])*P(edge(x, son)).然后再dfs一次考虑节 ...

  8. BZOJ3566:[SHOI2014]概率充电器(树形DP,概率期望)

    Description 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品——概率充电器: “采用全新纳米级加工技术,实现元件与导线能否通电完全由真随机数决定!SHOI 概率充电器, ...

  9. [CSP-S模拟测试]:树(树形DP+期望)

    题目描述 梦游中的你来到了一棵$N$个节点的树上.你一共做了$Q$个梦,每个梦需要你从点$u$走到点$v$之后才能苏醒,由于你正在梦游,所以每到一个节点后,你会在它连出去的边中等概率地选择一条走过去, ...

随机推荐

  1. laydate实现设置最小时间为当前时间

    当前时间之前的日期不能选择,添加个min,主要代码如下: var now = new Date(); startTime= laydate.render({ elem: '#test1', type: ...

  2. input 数值验证

    1.手动校验数字为整数 Number.isInteger <el-input class="radioInput" v-model.number="ruleForm ...

  3. [JZOJ3168] 【GDOI2013模拟3】踢足球

    题目 描述 题目大意 有两个队伍,每个队伍各nnn人. 接到球的某个人会再下一刻随机地传给自己人.敌人和射门,射门有概率会中. 每次射门之后球权在对方111号选手. 某个队伍到了RRR分,或者总时间到 ...

  4. Python学习day26-面向对象之小结

    figure:last-child { margin-bottom: 0.5rem; } #write ol, #write ul { position: relative; } img { max- ...

  5. Vue报错——Unknown custom element: <shop-slide> - did you register the component correctly?

    参考: https://blog.csdn.net/jiangyu1013/article/details/85676292 解决:除了import组件外,还要在components中添加 <t ...

  6. oracle日志

    UTL_FILE.FOPEN(location in varchar2, filename in varchar2, open_mode in varchar2) return FILE_TYPE; ...

  7. BZOJ4383/LuoGuP3588 Pustynia/PUS 线段树建图优化

    我会告诉你我看了很久很久才把题目看懂吗???怀疑智商了 原来他给的l,r还有k个数字都是下标... 比如给了一个样例 l, r, k, x1,x2,x3...xk,代表的是一个数组num[l]~num ...

  8. 12.Hibernate多对多关系

    JavaBean的编写 Person private long pid ; private String name ; private Set<Role> roles = new Hash ...

  9. 图解nginx配置负载均衡

    1. 在Linux上准备两份tomcat 2. 修改两份tomcat的端口号 修改的端口如图所示: 3. 启动两个tomcat服务器 4. 修改两个服务器上的主页方便测试区分 5. 在nginx配置文 ...

  10. create-react-app 创建项目失败

    创建失败后查阅相关资料,亲测删除 C:\Users\Administrator\AppData\Roaming\npm-cache\ 该文件夹下所有内容后成功.