Codeforces 696B Puzzles(期望+树形dp)
2017-02-02 21:40
411 查看
题意:
对树做dfs的时候,每一个点都有一个时间戳,问你如果每次选择子节点都是等概率的情况下,每个点的期望时间戳是多少。
解法:
一看就是典型的树形dp求期望的题目,我们考虑的是其他的点对某一个点的贡献度,最后的出的转移方程就是dp[v] = dp[u] + 1 + (sz[u] - sz[v] - 1]) * 0.5。
得到这个方程有两个方法,第一种很好理解,首先子节点最起码比父节点要大1,然后考虑这个子节点和其他兄弟节点的关系,其他的兄弟节点要么在他之前访问,要么在这时候访问,概率都是0.5,所以对这个店的贡献就是其他兄弟节点的子树大小乘以0.5;第二种,我们就需要推导一下公式,我就不具体写出来了,大概的思路就是假设当前节点是在所有兄弟节点中第i个被访问的,那么他的期望就是前面i-1个节点的期望再乘以概率计科,虽然对于某一次的期望的式子比较复杂,但是把他们都求和之后,就会发现能够消掉很多东西,最后也就得到了上面的式子。
代码力两次dfs就可以搞定,很简单。
对树做dfs的时候,每一个点都有一个时间戳,问你如果每次选择子节点都是等概率的情况下,每个点的期望时间戳是多少。
解法:
一看就是典型的树形dp求期望的题目,我们考虑的是其他的点对某一个点的贡献度,最后的出的转移方程就是dp[v] = dp[u] + 1 + (sz[u] - sz[v] - 1]) * 0.5。
得到这个方程有两个方法,第一种很好理解,首先子节点最起码比父节点要大1,然后考虑这个子节点和其他兄弟节点的关系,其他的兄弟节点要么在他之前访问,要么在这时候访问,概率都是0.5,所以对这个店的贡献就是其他兄弟节点的子树大小乘以0.5;第二种,我们就需要推导一下公式,我就不具体写出来了,大概的思路就是假设当前节点是在所有兄弟节点中第i个被访问的,那么他的期望就是前面i-1个节点的期望再乘以概率计科,虽然对于某一次的期望的式子比较复杂,但是把他们都求和之后,就会发现能够消掉很多东西,最后也就得到了上面的式子。
代码力两次dfs就可以搞定,很简单。
// Created by CQU_CST_WuErli // Copyright (c) 2016 CQU_CST_WuErli. All rights reserved. // //#pragma comment(linker, "/STACK:102400000,102400000") #include <iostream> #include <cstring> #include <cstdio> #include <cstdlib> #include <cctype> #include <cmath> #include <string> #include <vector> #include <map> #include <queue> #include <stack> #include <set> #include <algorithm> #include <sstream> #define CLR(x) memset(x,0,sizeof(x)) #define OFF(x) memset(x,-1,sizeof(x)) #define MEM(x,a) memset((x),(a),sizeof(x)) #define BUG cout << "I am here" << endl #define lookln(x) cout << #x << "=" << x << endl #define SI(a) scanf("%d", &a) #define SII(a,b) scanf("%d%d", &a, &b) #define SIII(a,b,c) scanf("%d%d%d", &a, &b, &c) const int INF_INT=0x3f3f3f3f; const long long INF_LL=0x7f7f7f7f; const int MOD=1e9+7; const double eps=1e-10; const double pi=acos(-1); typedef long long ll; using namespace std; int n; vector<int> g[100010]; int sz[100010]; double ans[100010]; void dfs1(int u) { sz[u] = 1; for (auto& v : g[u]) { dfs1(v); sz[u] += sz[v]; } } void dfs2(int u) { for (auto& v : g[u]) { ans[v] = ans[u] + 1 + (double)(sz[u] - sz[v] - 1) / 2.0; dfs2(v); } } int main(int argc, char const *argv[]) { #ifdef LOCAL freopen("C:\\Users\\john\\Desktop\\in.txt","r",stdin); // freopen("C:\\Users\\john\\Desktop\\out.txt","w",stdout); #endif while (SI(n) == 1) { for (int i = 1; i <= n; i++) g[i].clear(), sz[i] = 0, ans[i] = 0; for (int i = 2; i <= n; i++) { int x; SI(x); g[x].push_back(i); } dfs1(1); ans[1] = 1; dfs2(1); for (int i = 1; i <= n; i++) printf("%f\n", ans[i]); } return 0;
相关文章推荐
- Codeforces 696B Puzzles 树形期望dp
- Codeforces 581F Zublicanes and Mumocrates(树形DP)
- codeforces 855C Helga Hufflepuff's Cup (树形dp)
- Codeforces 461B. Appleman and Tree[树形DP 方案数]
- codeforces 219D Choosing Capital for Treeland(树形DP)
- codeforces 543d Road Improvement 树形dp (★ )
- codeforces 405 D. Bear and Tree Jumps 树形dp
- Codeforces 239E World Eater Brothers【思维+树形Dp】
- Codeforces 767C 树形dp
- codeforces 522A A. Reposts(树形dp)
- Codeforces 77C 树形DP
- codeforces 161D - Distance in Tree(树形dp)
- 【Codeforces 743D】 Chloe and pleasant prizes【树形dp】
- Codeforces-708C(树形DP)
- CodeForces 543d Road Improvement(巧妙地树形dp)
- Codeforces 682C Alyona and the Tree(树形DP)
- codeforces 533B B. Work Group(树形dp)
- Codeforces 700B Connecting Universities(树形DP)
- codeforces 802K Send the Fool Further! (medium) 树形dp
- Appleman and Tree - CodeForces 461 B 树形dp