有向图或者无向图概率dp
来源:互联网 发布:罗马音发音软件 编辑:程序博客网 时间:2024/06/05 14:10
概要:
一般形成环的用高斯消元法求解。但是递推公式只和少数变量相关,可以考虑分离出系数。
总结:
(看完下面的例题再来看这部分)
1.这类题型一般可以先写出原始公式然后分离出困难的变量,比如第二题的
2.将剩下的变量通过待定系数的公式带入消去,比如例题2,
3.写出结果公式*用递推出的系数求出结果
例题1:HDU4405
题意:有三个骰子,分别有k1,k2,k3个面。
每次掷骰子,如果三个面分别为a,b,c则分数置0,否则加上三个骰子的分数之和。
当分数大于n时结束。求游戏的期望步数。初始分数为0
设dp[i]表示达到i分时到达目标状态的期望,pk为投掷k分的概率,p0为回到0的概率
则dp[i]=∑(pk*dp[i+k])+dp[0]*p0+1;
都和dp[0]有关系,而且dp[0]就是我们所求,为常数
设dp[i]=A[i]*dp[0]+B[i];
代入上述方程右边得到:
dp[i]=∑(pk*A[i+k]*dp[0]+pk*B[i+k])+dp[0]*p0+1
=(∑(pk*A[i+k])+p0)dp[0]+∑(pk*B[i+k])+1;
明显A[i]=(∑(pk*A[i+k])+p0)
B[i]=∑(pk*B[i+k])+1
先递推求得A[0]和B[0].
那么 dp[0]=B[0]/(1-A[0]);
#include <set>#include <map>#include <queue>#include <vector>#include <math.h>#include <iostream>#include <stdio.h>#include <algorithm>#include <string.h>using namespace std;#define ff first#define ss second#define pb push_back#define ll long long#define mod 1000000007#define ull unsigned long long#define mst(ss,b) memset(ss,b,sizeof(ss));#define pl(x) cout << #x << "= " << x << endl;const int inf = 0x3f3f3f3f;const int N = 1e5+10;double dp[N];int n, m;int path[N], jump[N];int main(){ while(~scanf("%d%d", &n, &m)){ if(n == 0 && m == 0)break; mst(dp, 0); mst(path, -1); mst(jump, -1); for(int i=1; i<=m; i++){ int u, v; scanf("%d%d", &u, &v); path[u] = v; } for(int i=n; i>=1; i--){ int j = path[i]; if(j == -1)continue; if(jump[j] != -1)jump[i] = jump[j]; else jump[i] = j; } for(int i=n-1; i>=0; i--){ if(jump[i] != -1)dp[i] = dp[jump[i]]; else{ for(int j=1; j<=6; j++) dp[i] += dp[i+j]; dp[i] = dp[i]/6.0+1; } } printf("%.4f\n", dp[0]); } return 0;}
例题2:HDU 4035
dp求期望的题。
题意:
有n个房间,由n-1条隧道连通起来,实际上就形成了一棵树,
从结点1出发,开始走,在每个结点i都有3种可能:
1.被杀死,回到结点1处(概率为ki)
2.找到出口,走出迷宫 (概率为ei)
3.和该点相连有m条边,随机走一条
求:走出迷宫所要走的边数的期望值。
这题是树上的概率dp,上题是有向图,这题是无向图,父子结点的概率互相影响。
设dp[i]表示从i号结点走出迷宫时走过边数的概率,father[i]表示i号结点的父亲结点,child表示i号结点的儿子结点
递推公式求法可参考kuangbin的题解
http://www.cnblogs.com/kuangbin/archive/2012/10/03/2711108.html
#include <bits/stdc++.h>using namespace std;#define ff first#define ss second#define pb push_back#define ll long long#define mod 1000000007#define ull unsigned long long#define mst(ss,b) memset(ss,b,sizeof(ss));#define dbg(x) cout << #x << "= " << x << endl;typedef pair <int, int> pii;const int inf = 0x3f3f3f3f;const int N = 1e4+5;const double eps = 1e-12; //这题需要开小点double k[N], e[N];vector<int>E[N];double A[N], B[N], C[N];int n;bool dfs(int u, int pre){ int m = E[u].size(); A[u] = k[u]; B[u] = (1-k[u]-e[u])/m; C[u] = 1-k[u]-e[u]; double tmp = 1.0; for(int i=0; i<m; i++){ int v = E[u][i]; if(v == pre)continue; if(!dfs(v, u))return 0; A[u] += (1-k[u]-e[u])/m*A[v]; C[u] += (1-k[u]-e[u])/m*C[v]; tmp -= (1-k[u]-e[u])/m*B[v]; } if(fabs(tmp) < eps)return 0; A[u] /= tmp; B[u] /= tmp; C[u] /= tmp; return 1;}int main(){ int T; scanf("%d", &T); for(int kase=1; kase<=T; kase++){ printf("Case %d: ", kase); scanf("%d", &n); for(int i=1; i<=n; i++)E[i].clear(); for(int i=1; i<n; i++){ int u, v; scanf("%d%d", &u, &v); E[u].pb(v); E[v].pb(u); } for(int i=1; i<=n; i++){ int x, y; scanf("%d%d", &x, &y); k[i] = x/100.0; e[i] = y/100.0; } if(dfs(1, -1) && fabs(1-A[1]) > eps) printf("%.6f\n", C[1]/(1-A[1])); else puts("impossible"); } return 0;}
- 有向图或者无向图概率dp
- 有向图或者无向图是否存在环
- 概率无向图模型
- 概率有向图模型
- 概率图模型之有向图与无向图
- 概率图模型之有向图与无向图
- 有向图和无向图
- 无权图(有向或者无向)的 创建 插入边 删除边
- 邻接表-建立无向图、无向网、有向图、有向网
- 有向图、有向网、无向图、无向网
- 有向图与无向图判断有环
- 有向图,无向图,连通图,完全图
- 图(有向图、无向图)
- 有向图无向图的最小环。
- 邻接矩阵(有向图,无向图实现的差异)
- hdu1272 (无向图)/1325(有向图)
- 无向图和有向图的tarjan
- 数据结构: 无向图和有向图的API
- 【mysql】Centos6.5使用yum安装mysql——快速上手必备
- 第12条:考虑实现Comparable接口
- 计算多项式之积
- Mac 装VMWare虚拟机(win 7) 提供工具下载
- Linux 网卡的配置
- 有向图或者无向图概率dp
- Linux软件源(学习笔记)
- JS带缓存效果的移动函数封装
- CentOS7使用firewalld打开关闭防火墙与端口
- jdom操作xml
- Three.js 阴影效果
- C#调试AutoCAD自动装入图形和库文件
- Java奇淫巧技之Lombok
- 工具类网站