hdu 4035 可能性DP 成都网络游戏

http://acm.hdu.edu.cn/showproblem.php?pid=4035

获得:

1、首先推断是不是树。事实上,所有的感觉身影,既看边数==算-1是不成立

2、有时候,我告诉孩子来区分树仍然是必要的,就是,只是是在dfs的时候,传參数的时候多加个表示父节点的參数而已

3、一定注意,概率DP对精度真的要求非常高 開始的时候写1e-8,WA了好几发,改了1e-10  AC

4、注意分母为0的可能的时候加上推断

讲的非常具体的题解:http://blog.csdn.net/morgan_xww/article/details/6776947

直接按公式写的代码就是:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <iostream>
#include <iomanip>
#include <cmath>
#include <map>
#include <set>
#include <queue>
using namespace std;

#define ls(rt) rt*2
#define rs(rt) rt*2+1
#define ll long long
#define ull unsigned long long
#define rep(i,s,e) for(int i=s;i<e;i++)
#define repe(i,s,e) for(int i=s;i<=e;i++)
#define CL(a,b) memset(a,b,sizeof(a))
#define IN(s) freopen(s,"r",stdin)
#define OUT(s) freopen(s,"w",stdout)
const ll ll_INF = ((ull)(-1))>>1;
const double EPS = 1e-10;
const int INF = 100000000;
const int MAXN = 10000+100;

vector<int>g[MAXN];
double k[MAXN],e[MAXN];
double a[MAXN],b[MAXN],c[MAXN];
int n;

bool sea(int i, int fa)
{
    if(g[i].size() == 1 && fa!=-1)//叶子节点
    {
        a[i]=k[i];
        c[i]=b[i]=1.0-k[i]-e[i];
        return true;
    }
    //非叶子节点,此时该非叶子节点的子孙都已经遍历过了
    double aa=0.0,bb=0.0,cc=0.0;
    for(int j=0;j<g[i].size();j++)
    {
        if( g[i][j] == fa)continue;
        if(!sea(g[i][j],i))return 0;
        aa+=a[g[i][j]];
        bb+=b[g[i][j]];
        cc+=c[g[i][j]];
    }
    int m=g[i].size();
    a[i]=(k[i]+(1-k[i]-e[i])/m*aa)/(1-(1.0-k[i]-e[i])/m*bb);
    b[i]=(1.0-k[i]-e[i])/m/(1.0-(1.0-k[i]-e[i])/m*bb);
    c[i]=( (1.0-k[i]-e[i])+(1.0-k[i]-e[i])/m*cc )/(1.0 -(1.0-k[i]-e[i])/m*bb);
    return true;
}

int main()
{
    int ncase,u,v,ic=0;

    scanf("%d",&ncase);
    while(ncase--)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            g[i].clear();
        for(int i=1;i<n;i++)
        {
            scanf("%d%d",&u,&v);
            g[u].push_back(v);
            g[v].push_back(u);
        }
        for(int i=1;i<=n;i++)
        {
            scanf("%lf%lf",&k[i],&e[i]);
            k[i]/=100.0;
            e[i]/=100.0;
        }

        printf("Case %d: ",++ic);
        if(sea(1,-1) && fabs(1.0-a[1])>EPS)
            printf("%.6lf\n",c[1]/(1.0-a[1]));
        else
            printf("impossible\n");
    }
    return 0;
}

当然更好的写法还是题解上的

#include <cstdio>
#include <iostream>
#include <vector>
#include <cmath>  

using namespace std;  

const int MAXN = 10000 + 5;  

double e[MAXN], k[MAXN];
double A[MAXN], B[MAXN], C[MAXN];  

vector<int> v[MAXN];  

bool search(int i, int fa)
{
    if ( v[i].size() == 1 && fa != -1 )
    {
        A[i] = k[i];
        B[i] = 1 - k[i] - e[i];
        C[i] = 1 - k[i] - e[i];
        return true;
    }  

    A[i] = k[i];
    B[i] = (1 - k[i] - e[i]) / v[i].size();
    C[i] = 1 - k[i] - e[i];
    double tmp = 0;  

    for (int j = 0; j < (int)v[i].size(); j++)
    {
        if ( v[i][j] == fa ) continue;
        if ( !search(v[i][j], i) ) return false;
        A[i] += A[v[i][j]] * B[i];
        C[i] += C[v[i][j]] * B[i];
        tmp  += B[v[i][j]] * B[i];
    }
    if ( fabs(tmp - 1) < 1e-10 ) return false;
    A[i] /= 1 - tmp;
    B[i] /= 1 - tmp;
    C[i] /= 1 - tmp;
    return true;
}  

int main()
{
    int nc, n, s, t;  

    cin >> nc;
    for (int ca = 1; ca <= nc; ca++)
    {
        cin >> n;
        for (int i = 1; i <= n; i++)
            v[i].clear();  

        for (int i = 1; i < n; i++)
        {
            cin >> s >> t;
            v[s].push_back(t);
            v[t].push_back(s);
        }
        for (int i = 1; i <= n; i++)
        {
            cin >> k[i] >> e[i];
            k[i] /= 100.0;
            e[i] /= 100.0;
        }  

        cout << "Case " << ca << ": ";
        if ( search(1, -1) && fabs(1 - A[1]) > 1e-10 )
            cout << C[1]/(1 - A[1]) << endl;
        else
            cout << "impossible" << endl;
    }
    return 0;
} 

版权声明:本文博客原创文章,博客,未经同意,不得转载。

时间: 2024-10-11 11:12:29

hdu 4035 可能性DP 成都网络游戏的相关文章

hdu 4035 概率DP 成都网赛

http://acm.hdu.edu.cn/showproblem.php?pid=4035 学到: 1.先判断是不是树,其实凡是有图的感觉的,都看边数==点数-1是不是成立 2.树有时候区分老子跟孩子还是有必要的,这道题就是,不过是在dfs的时候,传参数的时候多加个表示父节点的参数而已 3.一定注意,概率DP对精度真的要求很高 开始的时候写1e-8,WA了好几发,改了1e-10  AC 4.注意分母为0的可能的时候加上判断 讲的很详细的题解:http://blog.csdn.net/morga

hdu 4035 概率dp

太吊了 1 /* 2 HDU 4035 3 4 dp求期望的题. 5 题意: 6 有n个房间,由n-1条隧道连通起来,实际上就形成了一棵树, 7 从结点1出发,开始走,在每个结点i都有3种可能: 8 1.被杀死,回到结点1处(概率为ki) 9 2.找到出口,走出迷宫 (概率为ei) 10 3.和该点相连有m条边,随机走一条 11 求:走出迷宫所要走的边数的期望值. 12 13 设 E[i]表示在结点i处,要走出迷宫所要走的边数的期望.E[1]即为所求. 14 15 叶子结点: 16 E[i] =

HDU 4035 期望dp

这道题站在每个位置上都会有三种状态 死亡回到起点:k[i] 找到出口结束 e[i] 原地不动 p[i] k[i]+e[i]+p[i] =1; 因为只给了n-1条路把所有都连接在一起,那么我们可以自然的把这张图看成一个树型结构 根据作为父亲节点和叶子节点作为区分 进行推导 详情可参考:http://blog.csdn.net/morgan_xww/article/details/6776947/ 1 #include <cstdio> 2 #include <cstring> 3 #

hdu 4035 2011成都赛区网络赛E 概率dp ****

太吊了,反正我不会 1 /* 2 HDU 4035 3 4 dp求期望的题. 5 题意: 6 有n个房间,由n-1条隧道连通起来,实际上就形成了一棵树, 7 从结点1出发,开始走,在每个结点i都有3种可能: 8 1.被杀死,回到结点1处(概率为ki) 9 2.找到出口,走出迷宫 (概率为ei) 10 3.和该点相连有m条边,随机走一条 11 求:走出迷宫所要走的边数的期望值. 12 13 设 E[i]表示在结点i处,要走出迷宫所要走的边数的期望.E[1]即为所求. 14 15 叶子结点: 16

hdu 4734 数位dp

http://acm.hdu.edu.cn/showproblem.php?pid=4734 Problem Description For a decimal number x with n digits (AnAn-1An-2 ... A2A1), we define its weight as F(x) = An * 2n-1 + An-1 * 2n-2 + ... + A2 * 2 + A1 * 1. Now you are given two numbers A and B, plea

hdu 3853 概率DP 简单

http://acm.hdu.edu.cn/showproblem.php?pid=3853 题意:有R*C个格子,一个家伙要从(0,0)走到(R-1,C-1) 每次只有三次方向,分别是不动,向下,向右,告诉你这三个方向的概率,以及每走一步需要耗费两个能量,问你走到终点所需要耗费能量的数学期望: 回头再推次,思想跟以前的做过的类似 注意点:分母为0的处理 #include <cstdio> #include <cstring> #include <algorithm>

HDU 4968 (水dp 其他?)

1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <vector> 5 #include <map> 6 using namespace std; 7 const int inf = 0x3f3f3f3f; 8 const int MAX = 200+10; 9 double GPA[10],dp1[20][30000],dp2[20][30000

hdu 4123 树形DP+RMQ

http://acm.hdu.edu.cn/showproblem.php?pid=4123 Problem Description Bob wants to hold a race to encourage people to do sports. He has got trouble in choosing the route. There are N houses and N - 1 roads in his village. Each road connects two houses,

HDU 3853 概率dp

LOOPS Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 125536/65536 K (Java/Others) Total Submission(s): 2337    Accepted Submission(s): 951 Problem Description Akemi Homura is a Mahou Shoujo (Puella Magi/Magical Girl).Homura wants to help he