HDU 5001 Walk(概率DP)

来源:互联网 发布:物以类聚人以群分 知乎 编辑:程序博客网 时间:2024/04/30 01:58

这题我一开始用DFS去写。会出现重复的问题。。后来看了别人递推的方法。其实好简单啊。还是做太少了,dp[i][j],代表第j步在i位置的概率,在推能到达某个位置的概率的时候,上一层要从不是要推的这个位置开始推下去,因为这一层如果到了,后面就不需要推了。

AC代码:

#include<cstdio>#include<ctype.h>#include<algorithm>#include<iostream>#include<cstring>#include<vector>#include<cstdlib>#include<stack>#include<cmath>#include<queue>#include<set>#include<map>#include<ctime>#include<string.h>#include<string>using namespace std;#define ll __int64#define eps 1e-10#define MOD 10000007double dp[55][10005];vector<int>a[55];int n,d;double cal(int p){    int i,j,k;    double temp = 0;    for(i = 1; i <= d; i++)    {        for(j = 1; j <= n; j++)        {            if(j == p) continue;            int sz = a[j].size();            double db = 1.0/(double)sz;            for(k = 0; k < sz; k++)                dp[a[j][k]][i] += dp[j][i-1]*db;        }        temp += dp[p][i];    }    return temp;}int main(){    #ifdef GLQ    freopen("input.txt","r",stdin);//    freopen("o2.txt","w",stdout);    #endif // GLQ    int t,i,j,m;    scanf("%d",&t);    while(t--)    {        scanf("%d%d%d",&n,&m,&d);        for(i = 1; i <= n; i++)            a[i].clear();        for(i = 1; i <= m; i++)        {            int t1,t2;            scanf("%d%d",&t1,&t2);            a[t1].push_back(t2);            a[t2].push_back(t1);        }        double fir = 1.0/(double)n,ans;        for(i = 1; i <= n; i++)        {            memset(dp,0,sizeof(dp));            for(j = 1; j <= n; j++)                dp[j][0] = fir;            ans = cal(i)+fir;            printf("%.10lf\n",1.0-ans);        }    }    return 0;}


0 0
原创粉丝点击