• 【算法总结】概率与期望相关


    〖相关资料

    《浅析竞赛中一类数学期望问题的解决方法》

    〖相关题目

    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 }
    View Code

    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 }
    View Code

    3.【bzoj4318】OSU!

    题意:见原题

    分析:Clove_uniqueの博客

     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 }
    View Code
  • 相关阅读:
    Java I/O基础
    Python基础篇(九)
    Python基础篇(八)
    thinkphp5中Indirect modification of overloaded element of XXX has no effect的解决办法
    关于json_encode转义斜杠的问题
    [thinkexceptionErrorException] glob() has been disabled for security reasons
    CentOS7 安装svn
    -bash: /usr/bin/yum: /usr/bin/python: bad interpreter: No such file or directory
    php在线编辑本地文件方法共享
    python一些不错的东西
  • 原文地址:https://www.cnblogs.com/zsnuo/p/7683319.html
Copyright © 2020-2023  润新知