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

〖相关资料

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

〖相关题目

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

 

转载于:https://www.cnblogs.com/zsnuo/p/7683319.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值