【概率期望】题目总结

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sizeof_you/article/details/84680448

今天讲了讲数学,期望这做了四道题,一块写个博客记一下

CF540D Bad Luck Island
容易想到设 f [ i ] [ j ] [ k ] f[i][j][k] 表示剩下 i i r r j j s s k k p p 时候的概率,然后枚举遇见的是哪两种人,算一下概率就好了,但算的时候注意不能直接算,因为同种的人不能遇见,所以要减掉

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define maxn 105
using namespace std;
int r,s,p;
double f[maxn][maxn][maxn],ans[3];

int main(){
	scanf("%d%d%d",&r,&s,&p);
	f[r][s][p]=1;
	for(int i=r;i>=0;i--)
		for(int j=s;j>=0;j--)
			for(int k=p;k>=0;k--){
				if(j && i) 
				f[i][j-1][k]+=f[i][j][k]*2*i*j/(double)((i+j+k)*(i+j+k-1)-i*(i-1)-j*(j-1)-k*(k-1));
				if(k && j) 
				f[i][j][k-1]+=f[i][j][k]*2*j*k/(double)((i+j+k)*(i+j+k-1)-i*(i-1)-j*(j-1)-k*(k-1));
				if(i && k) 
				f[i-1][j][k]+=f[i][j][k]*2*i*k/(double)((i+j+k)*(i+j+k-1)-i*(i-1)-j*(j-1)-k*(k-1));
			}
	for(int i=r;i>=0;i--) ans[0]+=f[i][0][0];
	for(int i=s;i>=0;i--) ans[1]+=f[0][i][0];
	for(int i=p;i>=0;i--) ans[2]+=f[0][0][i];
	printf("%.12lf %.12lf %.12lf\n",ans[0],ans[1],ans[2]);
	return 0;
}

CF696B Puzzles
因为对于一个节点 v v ,它父亲的子节点在它前面的概率都是 0.5 0.5 ,所以就可以预处理节点 s i z siz f [ v ] = f [ u ] + 0.5 × ( s i z [ u ] s i z [ v ] + 1 ) f[v]=f[u]+0.5\times (siz[u]-siz[v]+1)

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define N 100005
using namespace std;

inline int rd(){
	int x=0,f=1;char c=' ';
	while(c<'0' || c>'9') f=c=='-'?-1:1,c=getchar();
	while(c<='9' && c>='0') x=x*10+c-'0',c=getchar();
	return x*f;
}

int n,siz[N],cnt,to[N],nxt[N],head[N];
double f[N];

inline void add(int x,int y){
	to[++cnt]=y; nxt[cnt]=head[x]; head[x]=cnt;
}

void dfs1(int u,int fa){
	siz[u]=1;
	for(int i=head[u];i;i=nxt[i]){
		int v=to[i]; if(v==fa)continue;
		dfs1(v,u); siz[u]+=siz[v];
	}
}

void dfs2(int u,int fa){
	for(int i=head[u];i;i=nxt[i]){
		int v=to[i]; if(v==fa)continue;
		f[v]=f[u]+0.5*(siz[u]-siz[v]+1);
		dfs2(v,u);
	}
}

int main(){
	n=rd();
	for(int i=2;i<=n;i++){
		int fa=rd(); add(fa,i);
	}
	f[1]=1;
	dfs1(1,0); dfs2(1,0);
	for(int i=1;i<=n;i++) printf("%.1lf ",f[i]);
	return 0;
}

CF16E Fish
2 n 2^n 枚举还剩下的鱼的集合,然后枚举那两个鱼遇见,算每条鱼被吃掉的概率

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define maxn 20
using namespace std;
int n,ed,cnt[(1<<18)+5];
double a[maxn][maxn],f[(1<<18)+5];

inline int calc(int x){
	int ret=0;
	while(x){
		if(x&1) ++ret; x>>=1;
	} return ret;
}

int main(){
	scanf("%d",&n); ed=1<<n;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			scanf("%lf",&a[i][j]);
	for(int i=0;i<ed;i++) cnt[i]=calc(i);
	f[ed-1]=1;
	for(int i=ed-1;i>=1;i--)
		for(int j=1;j<=n;j++)
			if((1<<(j-1))&i)
			for(int k=j+1;k<=n;k++)
				if((1<<(k-1))&i){
					f[i^(1<<(k-1))]+=f[i]*2*a[j][k]/cnt[i]/(cnt[i]-1);
					f[i^(1<<(j-1))]+=f[i]*2*a[k][j]/cnt[i]/(cnt[i]-1);
				}
	for(int i=1;i<=n;i++)
		printf("%.6lf ",f[1<<(i-1)]);
	return 0;
}

CF601C Kleofáš and the n-thlon
一个有意思的题

注意到除了给定的这个人,其他人的水平都是一样的,这意味着我们可以先算出一个人的,再 × ( m 1 ) \times (m-1) 就是其他所有人的,所以就可以设 f [ i ] [ j ] f[i][j] 表示前 i i 场比赛得到了 j j 分的概率,这样给定人的排名期望就是分数比他小的那些值的和再 + 1 +1

滚动数组优化一下空间,然后记一个前缀和优化时间复杂度

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define maxn 105
#define maxm 100005
using namespace std;

inline int rd(){
	int x=0,f=1;char c=' ';
	while(c<'0' || c>'9') f=c=='-'?-1:1,c=getchar();
	while(c<='9' && c>='0') x=x*10+c-'0',c=getchar();
	return x*f;
}

int n,m,sc,a[maxn];
double f[2][maxm],sum,ans;

int main(){
	n=rd(); m=rd();
	for(int i=1;i<=n;i++){
		a[i]=rd(); sc+=a[i];
	}
	if(m==1) return puts("1"),0;
	f[0][0]=1; int now=1;
	for(int i=1;i<=n;i++){
		sum=f[now^1][0]; memset(f[now],0,sizeof f[now]);
		for(int j=1;j<=n*m;j++){
			f[now][j]+=sum,sum+=f[now^1][j];
			if(j>=a[i]) f[now][j]-=f[now^1][j-a[i]];
			if(j>=m) sum-=f[now^1][j-m];
			f[now][j]/=(m-1);
		}
		now^=1;
	}
	for(int i=n;i<sc;i++) ans+=f[now^1][i];
	printf("%.15lf\n",ans*(m-1)+1.0);
}

一些小技巧:
1. 1.当合法的不好算的时候可以用总数减去不合法的
2. 西 2.当一些东西的性质相同时可以先算出某一个,再用它去算所有的
3. 3.状态设计很重要,按情况可以设由起点开始和由终点倒推,一般是哪个好确定就从哪个开始

猜你喜欢

转载自blog.csdn.net/sizeof_you/article/details/84680448