Codeforces Round #362 (Div. 2) D Puzzles (DP)

1 篇文章 0 订阅

题目链接:点我点我


DP题各种不会呀不会

做比赛时候完全木有思路,只能看题解了


题意:给出N个点,包含N - 1 个点 p2, p3, ..., pn 其中pi 以 i 为父亲结点,求到达每个点的期望值

比如样例1:


出发点为1,因此1的期望值为1

对于2,有四种可能1->2,1->5->2,1->4->6->7->2,1->4->6->7->5->2,值分别为2,3,5,6因此2的期望值为(2+3+5+6)/4=4

对于4,有五种可能1->4,1->5->4,1->2->3->4,1->5->2->3->4值分别为2,3,4,5因此4的期望值为(2+3+4+5)/4=3.5


题解:对于节点 VU ,考虑三种情况:

        1.U是V的祖先节点,那么U的值必然大于V。

        2.U是V的子树中的节点,那么U的值必然小于U。

        3.以上两种情况均不满足,则设节点 X,Y,满足X!=Y,X是V但不是U的祖先节点,而Y是U但不是V的祖先节点,X和Y有相同的父节点,即该父节点到X与到Y的概率相等。可以看出U的值大于V的概率为0.5。

        因此只需通过dfs统计节点的非子节点数,根据公式推算即可(n:节点数,sub:包括节点本身在内的子节点数,h:祖先节点数,depth:节点所在深度)


代码:

#include<bits/stdc++.h>
using namespace std;

const int maxn = 100000+5;
vector<int>vc[maxn];
int sub[maxn]={0};
int ans[maxn]={0};
void DFS(int cur){
	sub[cur]=1;
	for(int i=0;i<vc[cur].size();i++){
		DFS(vc[cur][i]);
		sub[cur]+=sub[vc[cur][i]];
	}
	return;
}
void dfs(int cur,int dep){
	dep+=2;
	ans[cur]=dep;
	int sz=sub[cur]-1;
	for(int i=0;i<vc[cur].size();i++){
		dfs(vc[cur][i],dep+sz-sub[vc[cur][i]]);
	}
	return;
}
int main(void){
	int N;
	cin>>N;
	for(int i=2;i<=N;i++){
		int p;
		cin>>p;
		vc[p].push_back(i);
	}
	DFS(1);
	dfs(1,0);
	printf("%.1f",ans[1]/2.0);
	for(int i=2;i<=N;i++)
	printf(" %.1f",ans[i]/2.0);
	return 0;
}


       








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值