算法总结概率与期望相关
Posted zsnuo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法总结概率与期望相关相关的知识,希望对你有一定的参考价值。
〖相关资料〗
〖相关题目〗
1.【bzoj1415】[NOI2005] 聪聪和可可
题意:在一个魔法森林里,住着一只聪明的小猫聪聪和一只可爱的小老鼠可可。整个森林可以认为是一个无向图,图中有N 个美丽的景点,景点从1 至N编号。在景点之间有一些路连接。可可正在景点M (M ≤ N)处。以后的每个时间单位,可可都会选择去相邻的景点(可能有多个)中的一个或停留在原景点不动。而去这些地方所发生的概率是相等的。聪聪是很聪明的,所以,当她在景点C 时,她会选一个更靠近可可的景点,如果这样的景点有多个,她会选一个标号最小的景点。如果走完第一步以后仍然没吃到可可,她还可以在本段时间内再向可可走近5一步。在每个时间单位,假设聪聪先走,可可后走。在某一时刻,若聪聪和可可位于同一个景点,则可可就被吃掉了。问平均情况下,聪聪几步就可能吃到可可。
分析:bfs预处理+概率dp。详见:汤可因《浅析竞赛中一类数学期望问题的解决方法》。
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 using namespace std; 5 const int N=1e3+10; 6 int n,m,u,v,cat,mouse,cnt,head,tail; 7 int first[N],ind[N],q[N],dis[N][N],p[N][N]; 8 double f[N][N]; 9 struct edge{int to,next;}e[N*2]; 10 int read() 11 { 12 int x=0,f=1;char c=getchar(); 13 while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1;c=getchar();} 14 while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘;c=getchar();} 15 return x*f; 16 } 17 void ins(int u,int v){e[++cnt]=(edge){v,first[u]};first[u]=cnt;} 18 void bfs(int S) 19 { 20 head=tail=0;q[tail++]=S; 21 p[S][S]=dis[S][S]=0; 22 while(head!=tail) 23 { 24 u=q[head++];if(head>1000)head=0; 25 for(int i=first[u];i;i=e[i].next) 26 { 27 v=e[i].to; 28 if(dis[S][u]+1<dis[S][v]||(dis[S][u]+1==dis[S][v]&&p[S][u]<p[S][v])) 29 { 30 dis[S][v]=dis[S][u]+1; 31 if(dis[S][v]<=1)p[S][v]=v; 32 else p[S][v]=p[S][u]; 33 q[tail++]=v;if(tail>1000)tail=0; 34 } 35 } 36 } 37 } 38 double dfs(int a,int b) 39 { 40 if(f[a][b])return f[a][b]; 41 if(a==b)return f[a][b]=0; 42 if(p[a][b]==b||p[p[a][b]][b]==b)return f[a][b]=1; 43 double sum=dfs(p[p[a][b]][b],b); 44 for(int i=first[b];i;i=e[i].next) 45 sum+=dfs(p[p[a][b]][b],e[i].to); 46 return f[a][b]=sum/(ind[b]+1)+1; 47 } 48 int main() 49 { 50 memset(p,0x3f,sizeof(p));memset(dis,0x3f,sizeof(dis)); 51 n=read();m=read();cat=read();mouse=read(); 52 for(int i=1;i<=m;i++) 53 u=read(),v=read(),ind[u]++,ind[v]++,ins(u,v),ins(v,u); 54 for(int i=1;i<=n;i++)bfs(i); 55 printf("%.3lf",dfs(cat,mouse)); 56 return 0; 57 }
2.【bzoj1076】[SCOI2008]奖励关
题意:在奖励关里,系统依次随机抛出k次宝物,每次可以选择吃或者不吃(必须在抛出下一个宝物之前做出选择,且现在决定不吃的宝物以后也不能再吃)。宝物一共有n种,每次抛出这n种宝物的概率都相同且相互独立。获取第i种宝物将得到Pi分,但第i种宝物有一个前提宝物集合Si。只有当Si中所有宝物都至少吃过一次,才能吃第i种宝物。假设你采取最优策略,平均情况你一共能在奖励关得到多少分值?
分析:为了方便地判断状态是否合法,可以倒着枚举。
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 using namespace std; 5 const int N=16; 6 const int M=(1<<15)+10; 7 int m,n,x,mx,v[N],t[N],p[N]; 8 double f[105][M]; 9 int read() 10 { 11 int x=0,f=1;char c=getchar(); 12 while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1;c=getchar();} 13 while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘;c=getchar();} 14 return x*f; 15 } 16 int main() 17 { 18 m=read();n=read();p[1]=1;mx=(1<<n)-1; 19 for(int i=2;i<=n;i++)p[i]=p[i-1]<<1; 20 for(int i=1;i<=n;i++) 21 { 22 v[i]=read();x=read(); 23 while(x)t[i]|=p[x],x=read(); 24 } 25 for(int i=m;i>=1;i--) 26 for(int j=0;j<=mx;j++) 27 { 28 for(int k=1;k<=n;k++) 29 if((t[k]|j)==j)f[i][j]+=max(f[i+1][j],f[i+1][j|p[k]]+v[k]); 30 else f[i][j]+=f[i+1][j]; 31 f[i][j]/=n; 32 } 33 printf("%.6lf",f[1][0]); 34 return 0; 35 }
3.【bzoj4318】OSU!
题意:见原题。
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #define LL long long 5 using namespace std; 6 const int N=1e5+5; 7 int n; 8 double p,f[N],g[N],h[N]; 9 int read() 10 { 11 int x=0,f=1;char c=getchar(); 12 while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1;c=getchar();} 13 while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘;c=getchar();} 14 return x*f; 15 } 16 int main() 17 { 18 n=read(); 19 for(int i=1;i<=n;i++) 20 { 21 scanf("%lf",&p); 22 h[i]=p*(h[i-1]+1); 23 g[i]=p*(g[i-1]+2*h[i-1]+1); 24 f[i]=p*(f[i-1]+3*g[i-1]+3*h[i-1]+1)+(1-p)*f[i-1]; 25 } 26 printf("%.1lf",f[n]); 27 return 0; 28 }
以上是关于算法总结概率与期望相关的主要内容,如果未能解决你的问题,请参考以下文章