【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$之后才能苏醒,由于你正在梦游,所以每到一个节点后,你会在它连出去的边中等概率地选择一条走过去, ...
随机推荐
- IDEA使用Maven+Tomcat插件实现热部署
1 配置tomcat pom.xml <!-- tomcat7启动插件 --> <plugin> <groupId>org.apache.tomcat.maven& ...
- AnsiString, String, char,char
AnsiString 是一个类,String 是一个结构,char* 是一个指针 .String是Pascal的类型原型,因为C++中没有字符串数据类型的,因此使用char*来存储,char*必须是以 ...
- Django项目:CMDB(服务器硬件资产自动采集系统)--11--07CMDB文件模式测试采集硬件数据
#settings.py # ————————01CMDB获取服务器基本信息———————— import os BASEDIR = os.path.dirname(os.path.dirname(o ...
- webpack 清理旧打包资源插件
当我们修改带hash的文件并进行打包时,每打包一次就会生成一个新的文件,而旧的文件并 没有删除.为了解决这种情况,我们可以使用clean-webpack-plugin 在打包之前将文件先清除,之后再打 ...
- QQ邮箱发送信息
#以下库为python自带的库,不需要进行安装 #邮件发信动作 import smtplib #构造邮件内容 from email.mime.text import MIMEText #构造邮件头 f ...
- js 面向对象几种数据模式
一.单例模式: 把描述同一事物的属性和方法放在同一内存空间下,实现了分组的作用,防止同一属性或者方法冲突.我们把这种分组编写代码的模式叫做单例模式即普通的对象. 单例模式是项目开发中最常用的一种开发模 ...
- SPSS分析技术:多元方差分析
SPSS分析技术:多元方差分析 下面要介绍多元方差分析的内容,多元方差分析是研究多个自变量与多个因变量相互关系的一种统计理论方法,又称多变量分析.多元方差分析实质上是单因变量方差分析(包括单因素和多因 ...
- MVVM基础概念和理解
在MVVM模式中,View封装UI和UI逻辑,viewmodel封装presentation逻辑,model封装业务逻辑和数据. View类 View的责任是定义屏幕上的结构和外观,在完美的情况下,v ...
- js 使用script或template标签:分离js代码template中的HTML元素
参考:https://www.jianshu.com/p/332252abe016 方法一. script: <div id="app"> <com-first& ...
- Vue报错——Unknown custom element: <shop-slide> - did you register the component correctly?
参考: https://blog.csdn.net/jiangyu1013/article/details/85676292 解决:除了import组件外,还要在components中添加 <t ...