当前位置: 首页 > news >正文

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;  
} 


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

相关文章:

  • 如何用Nagios远程执行插件(NRPE)来检测服务器内存使用率
  • Android-往来:添加到联系人
  • 《嵌入式Linux软硬件开发详解——基于S5PV210处理器》——1.1 硬件系统资源
  • ajaxFileUpload plugin上传文件 chrome、Firefox中出现SyntaxError:unexpected token
  • 《C++编程风格(修订版)》——2.6 动态内存的回收
  • wp-query调用前几篇文章的方法
  • 《思科UCS服务器统一计算》一1.3 统一计算系统(UCS)
  • 从平凡通往伟大——大数据技术学习
  • 《UML面向对象设计基础》—第1章1.7节继承
  • 启动页广告
  • 深入理解Spark:核心思想与源码分析. 3.5 Hadoop相关配置及Executor环境变量
  • Nim各种pragma使用方法
  • 《设计工作室生存手册》—第1章1.8节设计师是守护者
  • iOS Sprite Kit教程之申请和下载证书
  • Xamarin.Android开发实践(八)
  • php的引用
  • 网络传输文件的问题
  • AzureCon上微软宣布了哪些容器相关的重磅消息
  • create-react-app做的留言板
  • CSS3 变换
  • Flex布局到底解决了什么问题
  • Python十分钟制作属于你自己的个性logo
  • 给第三方使用接口的 URL 签名实现
  • 机器人定位导航技术 激光SLAM与视觉SLAM谁更胜一筹?
  • 精彩代码 vue.js
  • 说说动画卡顿的解决方案
  • 通过来模仿稀土掘金个人页面的布局来学习使用CoordinatorLayout
  • 推荐一款sublime text 3 支持JSX和es201x 代码格式化的插件
  • 小程序 setData 学问多
  • 小试R空间处理新库sf
  • 一天一个设计模式之JS实现——适配器模式
  • #define、const、typedef的差别
  • #LLM入门|Prompt#3.3_存储_Memory
  • (bean配置类的注解开发)学习Spring的第十三天
  • (poj1.3.2)1791(构造法模拟)
  • (附源码)ssm学生管理系统 毕业设计 141543
  • (简单) HDU 2612 Find a way,BFS。
  • (深入.Net平台的软件系统分层开发).第一章.上机练习.20170424
  • (四)模仿学习-完成后台管理页面查询
  • (一)SpringBoot3---尚硅谷总结
  • (转)AS3正则:元子符,元序列,标志,数量表达符
  • (转)Linux下编译安装log4cxx
  • (转)memcache、redis缓存
  • (轉貼) 蒼井そら挑戰筋肉擂台 (Misc)
  • .NET DevOps 接入指南 | 1. GitLab 安装
  • .NET开源的一个小而快并且功能强大的 Windows 动态桌面软件 - DreamScene2
  • .NET学习全景图
  • .sdf和.msp文件读取
  • @ConditionalOnProperty注解使用说明
  • @Validated和@Valid校验参数区别
  • @基于大模型的旅游路线推荐方案
  • @开发者,一文搞懂什么是 C# 计时器!
  • [04] Android逐帧动画(一)
  • [android] 看博客学习hashCode()和equals()
  • [BZOJ 3531][Sdoi2014]旅行(树链剖分+线段树)