LightOJ - 1287 Where to Run (期望dp+记忆化)

题面:
Last night you robbed a bank but couldn't escape and when you just got outside today, the police started chasing you. The city, where you live in, consists of some junctions which are connected by some bidirectional roads.
题意:
没读懂,还是看了其他人的博客~~~
就是说有一个人抢了银行,被警察叔叔捉拿,他现在在一个图上到处乱跑,但是最终走得路线必须走完每一个点。在一个点上,可以静候五分钟,这个时候警察叔叔看不见你,也可以去下一个没有遍历过,并且走这条路可以遍历整个图的点,这几个选择随机选。如果走到了最后一个点,就会被抓,问最后被警察叔叔抓住的时间期望。
思路:
对于走到的最后一个点,期望显然是0(期望倒推)
对于其他点,假设可以走到 \(p-1\) 个点,加上静候五分钟的选项,一共 \(p\) 个选项。
记当前这个点的期望是\(E_x\)

\[E_x=\frac{1}{p}(E_x+5)+\frac{p-1}{p}*\frac{sum}{p-1} \]

其中,sum是后续节点的期望和
移项得:

\[E_x =\frac{5+sum}{p-1} \]

#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime>
#define fuck(x) cout<<#x<<" = "<<x<<endl;
#define debug(a,i) cout<<#a<<"["<<i<<"] = "<<a[i]<<endl;
#define ls (t<<1)
#define rs ((t<<1)+1)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 20;
const int maxm = 400;
const int inf = 2.1e9;
const ll Inf = 999999999999999999;
const int mod = 1000000007;
const double eps = 1e-6;
const double pi = acos(-1);

int Head[maxn],cnt;
struct edge{
    int v,Next,w;
}e[maxm];

void add_edge(int u,int v,int w){
    e[cnt].Next=Head[u];
    e[cnt].v=v;
    e[cnt].w=w;
    Head[u]=cnt++;
}
double dp[20][40000];
bool book[20][40000];
int tot;
bool vis[maxn];
void dfs(int u,int sta){
    if(book[u][sta]){return;}
    double sum =0;
    int p = 1;
    for(int k=Head[u];k!=-1;k=e[k].Next){
        if(vis[e[k].v]){continue;}
        int nsta = sta|(1<<e[k].v);
        vis[e[k].v]=true;
        dfs(e[k].v,nsta);
        vis[e[k].v]=false;;
        if(book[e[k].v][nsta]){
            book[u][sta]=true;
            sum+=dp[e[k].v][nsta]+e[k].w;
            p++;
        }
    }
    if(sta==tot){book[u][sta]=true;}
    if(p!=1)
    dp[u][sta] = (sum+5.0)/(1.0*p-1.0);
}


int main()
{
//    ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
#endif // ONLINE_JUDGE

    int T;
    scanf("%d",&T);
    int cas = 0;
    while(T--){
        memset(Head,-1,sizeof(Head));cnt=0;
        memset(dp,0,sizeof(dp));
        memset(book,0,sizeof(book));

        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++){
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            add_edge(x,y,z);
            add_edge(y,x,z);
        }
        tot = (1<<n)-1;
        vis[0]=true;
        dfs(0,1);
        vis[1]=false;
        printf("Case %d: %.6f\n",++cas,dp[0][1]);
    }

    return 0;
}

posted @ 2019-08-22 20:00  断腿三郎  阅读(245)  评论(0编辑  收藏  举报