Hdu 4219 Randomization?【树型Dp】好题~但是好难呀.

来源:互联网 发布:保山市大数据 编辑:程序博客网 时间:2024/05/22 12:09

Randomization?

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 297    Accepted Submission(s): 171


Problem Description
Random is the real life. What we see and sense everyday are absolutely randomly happened. Randomization is the process of making something random, as the nature.
Given a tree with N nodes, to be more precisely, a tree is a graph in which each pair of nodes has and only has one path. All of the edges’ length is a random integer lies in interval [0, L] with equal probability. iSea want to know the probability to form a tree, whose edges’ length are randomly generated in the given interval, and in which the path's length of every two nodes does not exceed S.
 

Input
The first line contains a single integer T, indicating the number of test cases.
Each test case includes three integers N, L, S. Then N - 1 lines following, each line contains two integers Ai and Bi, describing an edge of the tree.

Technical Specification
1. 1 <= T <= 512
2. 1 <= N <= 64
3. 1 <= L <= 8, 1 <= S <= 512
4. 1 <= Ai, Bi <= N
 

Output
For each test case, output the case number first, then the probability rounded to six fractional digits.
 

Sample Input
32 3 21 24 3 41 22 33 47 4 101 22 34 52 64 74 6
 

Sample Output
Case 1: 0.750000Case 2: 0.500000Case 3: 0.624832
 

Author
iSea@WHU
 

Source
首届华中区程序设计邀请赛暨第十届武汉大学程序设计大赛

树型Dp都好难呀、


题目大意:


给你N个点构成的一棵树。每条边的权值可以设定为【0,L】区间内的任意一个价值,问任意两点间距离都不超过S的设定方案的概率。


思路:


思路参考自网络代码,看懂好难呀。


①设定Dp【u】【len】表示从节点u到以节点u为根的子树中的所有点的最大距离是len的概率,并且需要奥正其子树节点中两两距离不超过S。


②那么考虑两两子节点进行合并(哇第一次见这种骚操作。)


③设定Dist【i】表示当前子节点v的子树中,距离节点u的最远距离为i的概率。

那么有:Dist【k+j】+=dp【v】【k】*(1/(L+1))这里j是枚举的从节点v到节点u这条路径上的长度。


④再设定temp【i】表示合并完当前节点v之后的dp【u】【i】的答案。

那么有:temp【max(j,k)】+=dp【u】【k】*Dist【j】;这里需要同时保证j+k<=S;

接下来每次合并结束之后,将dp【u】【i】更新为temp【i】,然后考虑合并下一个子节点v.


Ac代码:

#include<stdio.h>#include<string.h>#include<vector>using namespace std;vector<int>mp[150];double dp[65][515];int n,L,S;double mm;double Dist[525];double temp[525];void Dfs(int u,int from){    mm=1;    mm/=(double)(L+1);    for(int i=0; i<=S; i++)dp[u][i]=0;    dp[u][0]=1;    for(int i=0;i<mp[u].size();i++)    {        int v=mp[u][i];        if(v==from)continue;        else        {            Dfs(v,u);            for(int j=0;j<=S;j++)            {                Dist[j]=temp[j]=0;            }            for(int j=0;j<=L;j++)            {                for(int k=0;k<=S;k++)                {                    if(j+k<=S)                    Dist[j+k]+=mm*dp[v][k];                }            }            for(int j=0;j<=S;j++)            {                for(int k=0;k<=S-j;k++)                {                    temp[max(j,k)]+=dp[u][k]*Dist[j];                }            }            for(int j=0;j<=S;j++)dp[u][j]=temp[j];        }    }}int main(){    int t;    int kase=0;    scanf("%d",&t);    while(t--)    {        memset(dp,0,sizeof(dp));        scanf("%d%d%d",&n,&L,&S);        for(int i=1; i<=n; i++)mp[i].clear();        for(int i=0; i<n-1; i++)        {            int x,y;            scanf("%d%d",&x,&y);            mp[x].push_back(y);            mp[y].push_back(x);        }        Dfs(1,-1);        double output=0;        for(int i=0; i<=S; i++)        {            output+=dp[1][i];        }        printf("Case %d: %.6f\n",++kase,output);    }}








原创粉丝点击