标签:blog http io os ar for 2014 sp 代码
http://acm.hdu.edu.cn/showproblem.php?pid=5001
思路:dp计算出途径每个点的总概率,1-x即为所求解。
dp题,先介绍下dp[i][j]为第j步走在第i个点的概率,那么dp[i][j]=dp[x1][j-1]+dp[x2][j-1]+...,x1,x2为i 的相邻节点。上一步在相邻节点这一步才能走到该点嘛。
每个点概率要一个一个的算,当算到第ii个点时(没打错,ii个点与代码对应),从起点推起,起点嘛,算是第0步吧,每个点被选中几率1.0/n,直接计入ans,并将该状态记零,因为此部分概率已计入总概率,不用产生后继状态,防止重复计数。然后以每一步为一层,更新每个节点的概率,碰到所求的点ii 时将概率计入总数并该状态记零,同上,避免状态重复计算。如此即可。
代码(g++ %f不过,c++ %f %lf 都过,知道的同学路过请求告知):
#include<iostream>
#include<map>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn=55;
const int maxm=3000;
int first[maxn],v[maxm],nex[maxm],out[maxn];
double dp[55][10005];
int ecnt;
void add_(int a,int b)
{
out[a]++;
v[ecnt]=b;
nex[ecnt]=first[a];
first[a]=ecnt++;
}
int main()
{
int T,n,m,k,a,b;
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d",&n,&m,&k);
ecnt=0;
memset(out,0,sizeof out);
memset(first,-1,sizeof first);
for(int i=0;i<m;i++)
{
scanf("%d%d",&a,&b);
add_(a,b);add_(b,a);
}
for(int j=1;j<=n;j++)dp[j][0]=1.0/n;
for(int ii=1;ii<=n;ii++)
{
double ans=1.0/n;
dp[ii][0]=0;
for(int i=1;i<=k;i++)
{
for(int j=1;j<=n;j++)
{
dp[j][i]=0;
for(int e=first[j];~e;e=nex[e])
dp[j][i]+=(dp[v[e]][i-1]/out[v[e]]);
if(j==ii)ans+=dp[j][i],dp[j][i]=0;
}
}
dp[ii][0]=1.0/n;
printf("%.10f\n",1-ans);
}
}
return 0;
}poj 5001 Walk &&2014 ACM/ICPC Asia Regional Anshan Online 1005(dp)
标签:blog http io os ar for 2014 sp 代码
原文地址:http://blog.csdn.net/u014569598/article/details/39255151