您的位置:首页 > 其它

hdu5001 Walk (概率dp)

2016-08-20 10:07 274 查看

hdu5001

题目

给你一个图,告诉你走多少步,每一个点作为起点的可能性是相同的,走某一个点的概率也是相同的,问所有走法中不仅过某一个点的概率是多少。

思路

就是个套着概率外皮的dp,dp[i][j]表示走i步走到j的概率,最后结果就是1减去所有到这点的可能性。设了一个0点连向每一个点,表示随机选某个起点,那么总步数就会是d+1步了。

要检讨一下,今天再做竟然做不出来。。。

首先看不出每个结果有什么相关性,我却想从整体考虑,导致卡了很久。

而后知道一个个点考虑,却也没什么思路,其实就是“砍”,每个点能分配的就是它现有的概率值的开枝散叶,if(j==x) continue;就是把这一部分砍掉,哪怕后流进去的。。。。

代码

#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <iostream>
#include <stack>
#include <queue>

using namespace std;

double dp[10100][60];
vector<int> edge[60];
int n,m,d;

double solve(int x)
{
dp[0][0]=1;
double ans=0;
for(int i=0; i<=d; i++)
{
for(int j=0; j<=n; j++)
{
if(j==x) continue;
double p=1.0/edge[j].size();
for(int k=0; k<edge[j].size(); k++)
{
dp[i+1][edge[j][k]]+=dp[i][j]*p;
}
}
ans+=dp[i+1][x];
}
return 1.0-ans;
}

int main()
{
int T;
scanf("%d",&T);
while(T--)
{

scanf("%d%d%d",&n,&m,&d);
for(int i=0; i<=n; i++)
edge[i].clear();
for(int i=0; i<m; i++)
{
int a,b;
scanf("%d%d",&a,&b);
edge[a].push_back(b);
edge[b].push_back(a);
}
for(int i=1; i<=n; i++)
edge[0].push_back(i);

double ans;
for(int i=1; i<=n; i++)
{
memset(dp,0,sizeof(dp));
printf("%.10f\n",solve(i));
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: