概率/期望DP初步——BZOJ1415 聪聪和可可
期望相关:
数学期望,可以简单理解的加权平均数。设有一系列的值$x_i$,每个值被取到的概率为$p_i$,则期望$E=\sum\limits_{i=1}^n p_i x_i$。
期望具有线性性:$$E(aX+bY)=aE(X)+bE(Y)$$ $$E(XY)=E(X)E(Y)$$ 大概就是说求期望的时候正着反着乱序着乱搞求出来的都是对的。。。
基于期望的线性性,我们可以在概率和期望之间建立一定的递推关系,这样就可以通过动态规划来解决一些概率问题。
比如NOI2005的聪聪和可可。
题目大意:给定一个无向图,聪聪在起点,可可在终点,每个时刻聪聪会沿最短路走向可可两步(如果有多条最短路走编号最小的点),然后可可会等概率向周围走或不动,求平均多少个时刻后聪聪和可可相遇。
设聪聪在节点$x$,可可在节点$y$
设$f[u][v]$为聪聪在$u$可可在$v$时聪聪抓住可可的期望时间,$p[u][v]$为为聪聪在$u$可可在$v$时聪聪下一步会到达的节点,$degree[v]$为节点$v$的度;
显然,当$x=y$时$f[x][y]=0$;当$0<dis[x][y] \leqslant 2$时$f[x][y]=1$。
当$dis[x][y]>2$时,$$f[x][y]=\frac{f[p[x][y]][y]+\sum\limits_{e(y,k)} f[p[x][y]][k]}{degree[x]+1}$$
对每个节点进行一次SPFA求出p[][]
然后根据上述状态转移方程记忆化搜索就好。
1 #include<cstring> 2 #include<algorithm> 3 #include<cmath> 4 #include<cstdio> 5 #include<queue> 6 #define foru(i,x,y) for(int i=x;i<=y;i++) 7 using namespace std; 8 const int N=1e4+10; 9 struct edge{int to,nxt;}e[N*2]; 10 queue<int> q; 11 int head[N],vis[N],d[N],ne,n,m,s,t,p[1005][1005]; 12 double f[1005][1005]; 13 void add(int a,int b){e[++ne]=(edge){b,head[a]};head[a]=ne;} 14 void spfa(int x){ 15 memset(d,127,sizeof(d)); 16 memset(vis,0,sizeof(vis)); 17 q.push(x);d[x]=0;vis[x]=1; 18 while(!q.empty()){ 19 int k=q.front();q.pop(); 20 vis[k]=0; 21 for(int i=head[k];i;i=e[i].nxt){ 22 int v=e[i].to; 23 if(d[v]>d[k]+1||(d[v]==d[k]+1&&k<p[v][x])){ 24 d[v]=d[k]+1; 25 p[v][x]=k; 26 if(!vis[v]){ 27 q.push(v); 28 vis[v]=1; 29 } 30 } 31 } 32 } 33 } 34 35 double dfs(int x,int y){ 36 if(f[x][y]!=-1)return f[x][y]; 37 if(x==y){f[x][y]=0;return 0;} 38 if(p[x][y]==y||p[p[x][y]][y]==y){f[x][y]=1;return 1;}; 39 f[x][y]=dfs(p[p[x][y]][y],y);int d=0; 40 for(int i=head[y];i;i=e[i].nxt){ 41 d++; 42 int v=e[i].to; 43 f[x][y]+=dfs(p[p[x][y]][y],v); 44 } 45 (f[x][y]/=d+1); 46 f[x][y]+=1; 47 return f[x][y]; 48 } 49 50 int main(){ 51 int u,v; 52 scanf("%d%d",&n,&m); 53 scanf("%d%d",&s,&t); 54 foru(i,1,m){ 55 scanf("%d%d",&u,&v); 56 add(u,v);add(v,u); 57 } 58 foru(i,1,n)foru(j,1,n)f[i][j]=-1; 59 foru(i,1,n)spfa(i); 60 double ans=dfs(s,t); 61 printf("%.3lf\n",ans); 62 return 0; 63 }
DP一直是弱项,总是找不到套路,还是多做点题吧。