1. 程式人生 > >[填坑]期望概率DP 試煉場

[填坑]期望概率DP 試煉場

double ems %0 練習 can mage set www print

完成了新手村任務的Hallmeow,來到了試煉場提升自己

正當我在網上找題練習的時候,突然意識到原來的題庫裏有這個專項,但我一共沒做幾道題而且還渾渾噩噩的,OD找的題質量都沒話說,於是就把這些弄懂吧

[試煉場]BZOJ 1415 聰聰與可可

聰聰可以一下走兩步,而且聰聰先走,可可後走

我們預處理出來p[ i ][ j ]為聰聰在 i ,可可在 j 時聰聰下一步要走到哪,用n遍spfa即可

顯然,dp[ i ][ i ]=0

顯然,如果p[ i ][ j ]= j 或者 p[ p[ i ][ j ] ][ j ]= j 那麽沒等到可可走就被吃掉了,dp[ i ][ j ]=1

設 w 為與 j 有連邊的點, t 為 j 的度

技術分享

需要記憶化搜索,用已經更新的更新未更新的

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
#define pos(i,a,b) for(int i=(a);i<=(b);i++)
#define pos2(i,a,b) for(int i=(a);i>=(b);i--)
#define N 2000
struct haha{
    int next,to;
}edge[N];
int head[N],cnt=1;
int degree[N];
void add(int u,int v){
    degree[u]++;
    edge[cnt].to=v;
    edge[cnt].next=head[u];
    head[u]=cnt++;
}
int n,m;
int a,b;
int dis[N],flag[N];
int p[N][N];
void spfa(int st)  
{  
    int f[N],q[65540],v[N],from[N];  
    unsigned short r,h;  
    int i;  
    memset(f,0x3f,sizeof f);  
    f[st]=0;q[++r]=st;  
    while(r!=h)  
    {  
        int x=q[++h];  
        v[x]=0;  
        for(i=head[x];i;i=edge[i].next)  
            if(f[edge[i].to]>f[x]+1||f[edge[i].to]==f[x]+1&&x<from[edge[i].to])  
            {  
                f[edge[i].to]=f[x]+1;  
                from[edge[i].to]=x;  
                if(!v[edge[i].to])  
                    v[edge[i].to]=1,q[++r]=edge[i].to;  
            }  
    }  
    for(i=1;i<=n;i++)  
        if(i!=st)  
            p[i][st]=from[i];  
}  
double ans[N][N];
double dfs(int x,int y){
    if(x==y)  return ans[x][y]=0;
    if(p[x][y]==y)  return ans[x][y]=1;
    if(p[p[x][y]][y]==y) return ans[x][y]=1;
    if(ans[x][y]>=-1e-7)
       return ans[x][y];
    double re=1.0;int temp=p[p[x][y]][y];
    for(int i=head[y];i;i=edge[i].next){
        re+=dfs(temp,edge[i].to)/(degree[y]+1);
    }   
    re+=dfs(temp,y)/(degree[y]+1);
    return ans[x][y]=re;
}
int main(){
    scanf("%d%d%d%d",&n,&m,&a,&b);
    pos(i,1,m){
        int x,y;
        scanf("%d%d",&x,&y);
        add(x,y);
        add(y,x);
    }
    pos(i,1,n){
        spfa(i);
    }
    memset(ans,200,sizeof(ans));
    printf("%0.3lf",dfs(a,b));
    return 0;
}

  

[填坑]期望概率DP 試煉場