zoukankan      html  css  js  c++  java
  • 【BZOJ】1415 [Noi2005]聪聪和可可 期望DP+记忆化搜索

    【题意】给定无向图,聪聪和可可各自位于一点,可可每单位时间随机向周围走一步或停留,聪聪每单位时间追两步(先走),问追到可可的期望时间。n<=1000。

    【算法】期望DP+记忆化搜索

    【题解】首先因为聪聪的步数大于可可,所以不可能出现循环,因此是DAG上的期望DP,用记忆化搜索解决。

    每个点bfs预处理p[x][y]表示x走向y的第一步位置,设f[x][y]表示聪聪在x可可在y追上的期望时间。

    $$f(x,y)=sum_{z}frac{f(g[g[i][j]]][j],z)}{out[x]+1}+1$$

    其中z是y的邻点和y自身。

    再判断一下一步到达,两步到达和重叠(可可随机到聪聪处)的情况即可。

    复杂度O(n^2)。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int maxn=1010;
    struct edge{int from,v;}e[maxn*3];
    int n,m,a,b,ins[maxn],first[maxn],d[maxn],q[1010],p[maxn][maxn],tot;
    double f[maxn][maxn];
    void insert(int u,int v)
    {
        tot++;e[tot].v=v;e[tot].from=first[u];first[u]=tot;ins[u]++;
        tot++;e[tot].v=u;e[tot].from=first[v];first[v]=tot;ins[v]++;
    }
    double dp(int a,int b)
    {
        if(f[a][b])return f[a][b];
        if(a==b)return f[a][b]=0;
        if(p[a][b]==b||p[p[a][b]][b]==b)return f[a][b]=1;
        double ans=dp(p[p[a][b]][b],b);
        for(int i=first[b];i;i=e[i].from)
         ans+=dp(p[p[a][b]][b],e[i].v);
        return f[a][b]=ans/(1.0*ins[b]+1)+1;
    }
    void bfs(int x)
    {
        memset(d,-1,sizeof(d));
        int head=0,tail=0;d[x]=0;p[x][x]=0;
        for(int i=first[x];i;i=e[i].from)p[x][e[i].v]=e[i].v,d[e[i].v]=1,q[tail++]=e[i].v;
        while(head!=tail)
         {
             int y=q[head++];if(head>1000)head=0;int num=p[x][y];
             for(int i=first[y];i;i=e[i].from)
              if(d[e[i].v]==-1||((d[y]+1==d[e[i].v])&&num<p[x][e[i].v]))
               {
                   d[e[i].v]=d[y]+1;
                   p[x][e[i].v]=num;
                   q[tail++]=e[i].v;
                   if(tail>1000)tail=0;
               }
         }
    }
    int main()
    {
        scanf("%d%d%d%d",&n,&m,&a,&b);
        for(int i=1;i<=m;i++)
         {
             int u,v;
             scanf("%d%d",&u,&v);
             insert(u,v);
         }
        for(int i=1;i<=n;i++)bfs(i);
        printf("%.3lf",dp(a,b));
        return 0;
    }
    View Code
  • 相关阅读:
    java笔记之IO详解——序列流
    java笔记之IO详解——输出字符流
    java笔记之IO详解——输入字符流
    java笔记之IO详解——输出字节流
    Nginx同一个域名部署多个项目
    服务器安装mongo数据库
    服务器安装node
    服务器Nginx配置及文件目录
    笔记 [待整理]
    vue-cli3打包app物理按键失效的问题[已解决]
  • 原文地址:https://www.cnblogs.com/onioncyc/p/6514466.html
Copyright © 2011-2022 走看看