频道栏目
首页 > 资讯 > C++ > 正文

[概率dp] hdu 5001 Walk

14-09-23        来源:[db:作者]  
收藏   我要投稿

题意:n个点(1~n),m条边,走k次,双向边,每次随机走一条路,起点也随机,问不走到各个点的概率是多少。

思路:

概率dp[i][j][k] 前i步 走到j 走不到k的概率。

那么状态转移就是 j能走到的点,传递所有dp[i][j][k]的值乘上概率。

代码:

#include"cstdlib"
#include"cstdio"
#include"cstring"
#include"cmath"
#include"stack"
#include"algorithm"
#include"iostream"
#include"vector"
using namespace std;
#define N 300000
double dp[3][55][55];  //因为内存问题 用滚动数组
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n,m,d;
        scanf("%d%d%d",&n,&m,&d);
        vectoredge[55];
        while(m--)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            edge[a].push_back(b);
            edge[b].push_back(a);
        }
        memset(dp,0,sizeof(dp));
        int i,j,k,l;
        for(i=1; i<=n; i++)
        {
            for(j=1; j<=n; j++)
            {
                if(j!=i) dp[0][i][j]+=1.0/n;  //初始化,就是因为起点在i所以走不到j的概率都是n分之1
            }
        }
        for(i=1; i<=d; i++)
        {
            memset(dp[i%2],0,sizeof(dp[i%2]));
            for(j=1; j<=n; j++)
            {
                for(k=0; k<(int)edge[j].size(); k++)
                {
                    for(l=1; l<=n; l++)
                    {
                        if(j!=l&&j!=edge[j][k]) dp[i%2][edge[j][k]][l]+=dp[1-i%2][j][l]*1.0/edge[j].size();
                    }
                }
            }
        }
        double ans[55];
        memset(ans,0,sizeof(ans));
        for(i=1; i<=n; i++)
        {
            for(j=1; j<=n; j++)
                if(i!=j) ans[i]+=dp[d%2][j][i];
        }
        for(i=1; i<=n; i++)
            printf("%.10f\n",ans[i]);
    }
    return 0;
}


相关TAG标签
上一篇:JavaFX战旗类游戏开发 第六课 移动范围的获取
下一篇:Java数据结构和算法(三)——简单排序
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站