「CF696B」Puzzle 题解 (期望与树形综合DP)
题目简介
给一颗树,按 序遍历并编号,对每个点求其编号的期望值。
分析
鄙人的想法与题解区稍微有点区别(尽管结论一样,过程却繁杂得多),希望不被大佬们嫌弃。
令表示结点 的期望值,表示以 为根的子树大小,考虑当前结点为 怎么向其子节点 转移。
令 有 个儿子:
-
假设在 选择的第一个结点就是 ,那么 将等于 ,而概率是 ;
-
假设在 选择的第一个结点不是 ,第二个结点是 ,那么 有 种不同的编号,分别是 ,因此总贡献为 ,每种的概率都是 ;
-
依此类推,假设 在第三个被选择,那么总贡献将为 ,相应的概率均为 ;
-
综上,可以得到一个状态转移方程:
这么去推肯定大大的,考虑化简。
令
由此得到转移:
#include<cstdio>
#include<iostream>
#include<vector>
using namespace std;
const int Maxn=1e5+5;
vector<int>tr[Maxn];
long double f[Maxn];
int siz[Maxn];
void dfs1(int x){
siz[x]=1;
for(auto y:tr[x]){
dfs1(y);
siz[x]+=siz[y];
}
}
void dfs2(int x){
for(auto y:tr[x]){
f[y]=f[x]+1.0*(siz[x]-siz[y]-1)/2+1;
dfs2(y);
}
}
int main(){
int n;cin>>n;
for(int i=2;i<=n;++i){
int x;cin>>x;
tr[x].push_back(i);
}
f[1]=1;
dfs1(1);dfs2(1);
for(int i=1;i<=n;++i)printf("%.7Lf ",f[i]);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现