hdu 5001 概率DP 图上的DP

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

当时一看是图上的就跪了 不敢写,也没退出来DP方程

感觉区域赛的题  一则有一个点难以想到 二则就是编码有点难度。

这个题:

我一直的思路就是1-能到达i的概率 就是不能到达i的概率,然后三维方程巴拉巴拉,,,,把自己搞迷糊

正确做法:

dp[k][j]   经过j步到达k点 并且不经过i点的概率 这么设的原因是,就可以求不能到达i点的概率了。   不能到达i点的概率就是segma(dp[v][j-1]/g[v].size())    v是与k相邻的结点,如果j-1步到达v 第j步就有1/g[v].size()的可能性到达k点

//#pragma comment(linker, "/STACK:102400000,102400000")
#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-8;
const double pi = acos(-1.0);
const int INF = 100000000;

const int MAXN = 60;
const int MAX = 10000+100;

double ans[MAXN];
double dp[MAXN][MAX];
vector<int>g[MAX];
int n,m,d;

void solve()
{
    for(int i=1;i<=n;i++)
    {
        CL(dp,0);
        for(int j=1;j<=d;j++)
        {
            if(j==1)
            {
                for(int k=1;k<=n;k++)
                   if(k!=i) dp[k][j]=1.0/n;  //第一步随机选一个点,可以到达任何一个点,所以概率都是1.0/n
            }
            else
            {
               for(int k=1;k<=n;k++)
                   if(k!=i)
                   {
                      for(int t=0;t<g[k].size();t++)
                      {
                          int v=g[k][t];
                          if(v!=i)dp[k][j]+=dp[v][j-1]/g[v].size();
                      }
                   }
            }
        }
        double out=0.0;
        for(int j=1;j<=n;j++)
            if(j!=i)out+=dp[j][d];
        printf("%.10lf\n",out);
    }
}

int main()
{
    //IN("hdu5001.txt");
    int ncase;
    scanf("%d",&ncase);
    while(ncase--)
    {
        for(int i=0;i<=n;i++)g[i].clear();
       // for(int i=0;i<=n;i++)ans[i]=0.0;
        scanf("%d%d%d",&n,&m,&d);
        d++;//
        int u,v;
        for(int i=0;i<m;i++)
        {
            scanf("%d%d",&u,&v);
            g[u].push_back(v);
            g[v].push_back(u);
        }
        solve();
    }
    return 0;
}
时间: 2024-12-28 06:24:42

hdu 5001 概率DP 图上的DP的相关文章

HDU 5001 概率dp

Walk Time Limit : 30000/15000ms (Java/Other)   Memory Limit : 65536/65536K (Java/Other) Special Judge Font: Times New Roman | Verdana | Georgia Font Size: ← → Problem Description I used to think I could be anything, but now I know that I couldn't do

HDU 6105 Gameia(图上博弈)

题目链接 题意: 有一棵树,所有的节点都是没有涂色的,Alice和Bob依次给没有涂色的节点涂色,Alice涂白色(先手),Bob涂黑色并且会把与这个黑色节点有树边直接相连的节点都涂成黑色(无论这个节点之前是白色还是没有涂色),Bob还有k次机会每次可以删掉一条树边(任何时候都可以执行),直到树上的所有节点都有涂色游戏结束.若树上至少有一个节点是白色Alice获胜,否则Bob获胜. 分析: Alice先涂一个白色节点,如果Bob想获胜,就必须找到一个未涂色的节点且该节点与白色节点有边相连(相当于

Hdu 5001 Walk 概率dp

Walk Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5001 Description I used to think I could be anything, but now I know that I couldn't do anything. So I started traveling. The nation looks like a connected bid

HDU 3249 Test for job (有向无环图上的最长路,DP)

 解题思路: 求有向无环图上的最长路,简单的动态规划 #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <algorithm> #include <vector> #include <cmath> #define LL long long using namespace std; const int

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>

ZOJ 3644 Kitty&#39;s Game (图上DP 约数)

哎-这一场就做了三个题目,全队倒数第一,简直是太弱了. A Kitty's Game (ZOJ 3644) 题目链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3644 题意: 给出一个有向图,每个节点有一个权值pi, 有一个人从1节点出发(其权值为1节点的权值),前往n号节点,每经过一个节点,他的权值就变成了他经过这个节点前的权值和这个节点权值的最小公倍数,如果他经过这个节点后权值不发生变化则他就不能经过这个节点

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

poj 3635 Full Tank? ( 图上dp )

题意: 已知每个点的加油站的油价单价(即点权),每条路的长度(边权). 有q个询问,每个询问包括起点s.终点e和油箱容量. 问从起点走到终点的最小花费.如果不可达输出impossible,否则输出最小的旅途费用. 算法: 其实要分析状态= =感觉就像是dp. 最直接的想法是  每到一个点都加上要走到下一个点所需要的油量.但是走的路不同,到底怎么处理加多少的问题呢? 因此想到分解状态,即拆点.每到一个点都+1单位的油量,然后把这个状态加入队列.另外如果现在油箱内的油足够达到下一点, 则更新状态,把

poj 3249 Test for Job 图上dp(记忆化搜索)

题意: 给一个n个点的DAG,每个点有一个值p,现在要在图上找一个入度为0到出度为0的路径,使路径上的点的p值和最大. 分析: dp[v]记录以点v为起点能获得的最大值,搜一遍即可. 代码: //poj 3249 //sep9 #include <iostream> using namespace std; const int maxN=100024; const int maxM=1000024; int n,m,e; int p[maxN],head[maxN],dp[maxN],vis[