【JZOJ5233】【GDOI模拟8.5】概率博弈 树形dp+期望
题面
小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,的方案数。
这个可以用树形背包弄出来,注意奇偶性。
然后就能统计答案了。
\]
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+期望的更多相关文章
- [CF697D]Puzzles 树形dp/期望dp
Problem Puzzles 题目大意 给一棵树,dfs时随机等概率选择走子树,求期望时间戳. Solution 一个非常简单的树形dp?期望dp.推导出来转移式就非常简单了. 在经过分析以后,我们 ...
- BZOJ 3566: [SHOI2014]概率充电器 [树形DP 概率]
3566: [SHOI2014]概率充电器 题意:一棵树,每个点\(q[i]\)的概率直接充电,每条边\(p[i]\)的概率导电,电可以沿边传递使其他点间接充电.求进入充电状态的点期望个数 糖教题解传 ...
- Codeforces 123E Maze(树形DP+期望)
[题目链接] http://codeforces.com/problemset/problem/123/E [题目大意] 给出一棵,给出从每个点出发的概率和以每个点为终点的概率,求出每次按照dfs序从 ...
- BZOJ2878 [Noi2012]迷失游乐园 【基环树 + 树形dp + 期望dp】
题目链接 BZOJ2878 题解 除了实现起来比较长,思维难度还是挺小的 观察数据范围发现环长不超过\(20\),而我们去掉环上任何一个点就可以形成森林 于是乎我们枚举断掉的点,然后只需求出剩余每个点 ...
- CF839 C 树形DP 期望
给一颗树,求从根出发路径长度的期望是多少. 树形DP 要想清楚期望的计算 /** @Date : 2017-08-12 23:09:41 * @FileName: C.cpp * @Platform: ...
- Codeforces 804D Expected diameter of a tree(树形DP+期望)
[题目链接] http://codeforces.com/contest/804/problem/D [题目大意] 给你一个森林,每次询问给出u,v, 从u所在连通块中随机选出一个点与v所在连通块中随 ...
- BZOJ 3566: [SHOI2014]概率充电器( 树形dp )
通过一次dfs求出dp(x)表示节点x考虑了x和x的子树都没成功充电的概率, dp(x) = (1-p[x])π(1 - (1-dp[son])*P(edge(x, son)).然后再dfs一次考虑节 ...
- BZOJ3566:[SHOI2014]概率充电器(树形DP,概率期望)
Description 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品——概率充电器: “采用全新纳米级加工技术,实现元件与导线能否通电完全由真随机数决定!SHOI 概率充电器, ...
- [CSP-S模拟测试]:树(树形DP+期望)
题目描述 梦游中的你来到了一棵$N$个节点的树上.你一共做了$Q$个梦,每个梦需要你从点$u$走到点$v$之后才能苏醒,由于你正在梦游,所以每到一个节点后,你会在它连出去的边中等概率地选择一条走过去, ...
随机推荐
- IDA*算法——骑士精神
例题 骑士精神 Description 在一个5×5的棋盘上有12个白色的骑士和12个黑色的骑士, 且有一个空位.在任何时候一个骑士都能按照骑士的走法(它可以走到和它横坐标相差为1,纵坐标相差为2或者 ...
- JavaScript设置body高度为浏览器高度的方法
document.getElementsByTagName('body')[0].style.height = window.innerHeight+'px';
- csp-s模拟测试10.1(b)X 国的军队,排列组合, 回文题解
题面:https://www.cnblogs.com/Juve/articles/11615883.html X 国的军队: 好像有O(T*N)的直接贪心做法 其实多带一个log的二分也可以过 先对所 ...
- 0907NOIP模拟测试赛后总结
120分rank26.我又被打回原型了…… 下午考的.中午由于种种原因并没有睡好.于是状态很差. 第一眼看题感觉T1是一道XX题.部分分竟然给这么肥 然后看T2.T3好像都还不是特别恶心的题目,挺常规 ...
- duilib教程之duilib入门简明教程1.前言
关于duilib的介绍就不多讲了,一来不熟,二来小伙伴们想必已经对比了多个界面库,也无需赘述.下面进入正题: 不看广告看疗效! 已有众多知名公司采用duilib做为界面库,如华为网盘.PPS(P ...
- 深入浅出 Java Concurrency (28): 线程池 part 1 简介[转]
从这一节开始正式进入线程池的部分.其实整个体系已经拖了很长的时间,因此后面的章节会加快速度,甚至只是一个半成品或者简单化,以后有时间的慢慢补充.完善. 其实线程池是并发包里面很重要的一部分,在实际情况 ...
- jeecms vue-cli项目结构详解
Vue-cli是vue官方出品的快速构建单页应用的脚手架,如果你是初次尝试Vue,不建议使用,推荐你使用普通引入javascript文件的方式进行学习,如果你已经有vue基础那么就可以用vue-cli ...
- 从xmlns的作用说起
查了资料和自己实践后,得出了一些关于xml和xmlns的结论 看一个最常见的javaweb 中xml配置文件的开头: <?xml version="1.0" encoding ...
- Sping中的AOP
AOP(Aspect Oriented Programming)面向切面编程,什么是切面.形象的说,我们编写的代码都是一种有序的流程,比如产品管理,订单管理,而切面就是垂直于这些流程的. 比如日志服务 ...
- 《DSP using MATLAB》Problem 8.11
代码: %% ------------------------------------------------------------------------ %% Output Info about ...