概率与期望
题意:
每个时间单位,可可都会选择去相邻的景点(可能有多个)中的一个或停留在原景点不动。
而去这些地方所发生的概率是相等的。
当聪聪在景点 C 时,她会选一个更靠近 可可的景点,如果这样的景点有多个,她会选一个标号最小的景点。
聪聪可以走一步或两步
在每个时间单位,假设聪聪先走,可可后走。若聪聪和可可位 于同一个景点,则可可就被吃掉了。
细节:
猫可以走一步或两步;
老鼠可以不动;
猫必须走到离老鼠最近的点,如距离有相同,则选编号最小的点。
分析:
聪聪的移动位置是由可可的位置决定的
#include<bits/stdc++.h> using namespace std; #define N 1005 int to[N<<1],nex[N<<1],head[N],vis[N],dis[N][N],nx[N][N],tot=0,viss[N][N]; double dp[N][N],du[N]; void add(int a,int b) { to[++tot]=b; nex[tot]=head[a]; head[a]=tot; } queue<int >q; void spfa(int s) { memset(vis,0,sizeof(vis)); q.push(s); dis[s][s]=0; while(!q.empty()){ int u=q.front(); q.pop(); if(vis[u]) continue; vis[u]=1; for(int i=head[u];i;i=nex[i]){ int v=to[i]; if(dis[s][u]+1<dis[s][v]){ dis[s][v]=dis[s][u]+1; if(!vis[v]) q.push(v); } } } } double dpp(int u,int v) { //printf("%d %d\n",u,v); if(viss[u][v]) return dp[u][v]; if(u==v) return 0; int step1=nx[u][v]; int step2=nx[step1][v]; if(step1==v||step2==v) return 1; double k=du[v]+1; for(int i=head[v];i;i=nex[i]){ int vv=to[i]; dp[u][v]+=(dpp(step2,vv)+1.0)/k; //printf("%lf\n",dp[u][v]); } dp[u][v]+=(dpp(step2,v)+1.0)/k*1.0; viss[u][v]=1; return dp[u][v]; } int main() { int n,m,s,t,a,b; scanf("%d%d",&n,&m); scanf("%d%d",&s,&t); for(int i=1;i<=m;i++) scanf("%d%d",&a,&b),add(a,b),add(b,a),du[a]+=1.0,du[b]+=1.0; memset(dis,0x7f7f7f,sizeof(dis)); memset(nx,0x7f7f7f,sizeof(nx)); for(int i=1;i<=n;i++) spfa(i); for(int i=1;i<=n;i++) for(int j=head[i];j;j=nex[j]){ int v=to[j]; for(int k=1;k<=n;k++) if(dis[i][k]==dis[v][k]+1) nx[i][k]=min(nx[i][k],v); } /*for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++) printf("%d ",nx[i][j]); printf("\n"); }*/ printf("%.3lf\n",dpp(s,t)); }
要想统计答案 就必须要先计算出聪聪在i位置 可可在j位置 聪聪下一步的移动方案
先用spfa对每一个点跑最短路 再统计聪聪下一个点应该走什么
然后用记忆化搜索 如果走到了return 0 或者差一两步走到return 1
否则就由大家都向前走的dp值推过来(猫肯定优选走两步)
由于猫走的路线已经定了 枚举鼠走哪一个点 概率就是鼠原来所在的点的出度+1(可以停留)