【概率dp,难度3颗星】hdu-5001(2014鞍山网络赛)

给你一个连通的无向图,等概率随机选取一个起点,走d步,每一步等概率走到相邻的点。问走完d步之后,每个点没有被经过的概率

推状态的关键当然就是对这个“从任意起点走完d步点node没被经过的概率”的理解了,转一下方向,这句话的意思其实等价于“我避开点node走d步到达其它点的概率之和”;

设状态方程p[node][d][i]为避开node走d步到达i点的概率,那么Σp[node][n][i],(i=1~n)即“从任意起点走完d步点node没被经过的概率”

初始时每个点的状态相当于走0步到达该点的状态,即p[node][0][i] = 1.0/n,(i != node);

之后,走d步到达i点的概率等价于走d-1步到达与i邻接的点g[i][j]的概率和,(g[i][j] != node);

根据以上分析求解就很容易了。因为是分别求点所以可以把数组第一维省略掉节省内存。

主要代码:

 1 void dp()
 2 {
 3     for(int i = 1; i <= n; i++) p[0][i] = 1.0/n;
 4     for(int node = 1; node <= n; node++)
 5     {
 6         for(int d = 1; d <= k; d++)
 7             for(int i = 0; i <= n; i++)
 8                 p[d][i] = 0;
 9 
10         for(int d = 1; d <= k; d++)
11             for(int i = 1; i <= n; i++)
12             {
13                 if(i == node) continue ;
14                 double sum = 0.0;
15                 int sz = g[i].size();
16                 if(sz == 0)  continue;
17                 for(int j = 0; j < g[i].size(); j++)
18                 {
19                     if(g[i][j] == node) { continue ;}
20                     sum += p[d-1][g[i][j]];
21                 }
22                 p[d][i] = sum/(sz);
23             }
24         double ans = 0.0;
25         for(int i = 1; i <= n; i++)
26         {
27             ans += p[k][i];
28         }
29         printf("%.10lf
", ans);
30     }
31 }
hdu 5001
原文地址:https://www.cnblogs.com/LLGemini/p/4717317.html