【CodeForces - 697D】Puzzles(树形dp,期望dp)
生活随笔
收集整理的這篇文章主要介紹了
【CodeForces - 697D】Puzzles(树形dp,期望dp)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目大意:
給定一棵樹,從1開始,按DFS的方式訪問這棵樹?
每次從父親節點隨機訪問兒子,問每個節點被訪問到的時間的期望
輸入:第一行一個數n,代表n個節點。第二行n-1個數p2,p3,p4,p5...,pn-1,其中pi代表i號節點的父節點編號,1號節點一定是根節點。
Examples
Input
7 1 2 1 1 4 4Output
1.0 4.0 5.0 3.5 4.5 5.0 5.0Input
12 1 1 2 2 4 4 3 3 1 10 8Output
1.0 5.0 5.5 6.5 7.5 8.0 8.0 7.0 7.5 6.5 7.5 8.0解題報告:
假設當前考慮的是根節點u,對于根節點的子節點,隨機產生的一個排列當訪問序列,對于某個兒子v,考慮其任意一個兄弟b,該兄弟在其前面的概率均為?1/2。所以這個兄弟對期望的貢獻為size(b) ,考慮完所有兄弟,對期望的貢獻即為 size[u]-size[v]?
所以期望即為 dp[u]+1+size[u]-size[v]。兩遍dfs即可。
AC代碼:
#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<stack> #include<map> #include<vector> #include<set> #include<string> #include<cmath> #include<cstring> #define FF first #define SS second #define ll long long #define pb push_back #define pm make_pair using namespace std; typedef pair<int,int> PII; const int MAX = 2e5 + 5; int n,fa[MAX],size[MAX]; double dp[MAX]; vector<int> vv[MAX]; void dfs(int u,int f) {int up = vv[u].size();size[u] = 1;for(int i = 0; i<up; i++) {int v = vv[u][i];if(v == f) continue;dfs(v,u);size[u] += size[v];}} void dfs2(int u,int f) {int up = vv[u].size();for(int i = 0; i<up; i++) {int v = vv[u][i];if(v == f) continue;dp[v] = dp[u] + 1 + (size[u]-size[v]-1)/2.0;dfs2(v,u);} } int main() {cin>>n;for(int i = 2; i<=n; i++) { scanf("%d",fa+i);vv[fa[i]].pb(i);} dfs(1,0);dp[1]=1;dfs2(1,0);for(int i = 1; i<=n; i++) printf("%.2f ",dp[i]);return 0 ; }?
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的【CodeForces - 697D】Puzzles(树形dp,期望dp)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 银行的麻烦来了?年内近3000家网点遭关
- 下一篇: 个人破产制度最新进展,这一省份正式“官宣