题目大意
有
m
个游客, 他们都依次访问城市
设
ci
个乘客经过了城市
i
,则第
求每个人的快乐值之和的期望
m,n≤16
题解
枚举城市
x
和经过当前城市的人的状态
设当前状态的人数为 cnt ,出现概率为 ps ,所有经过当前城市的人的 pi 的和为 pn
枚举每个人
i
,
当前状态出现概率×第i个人走到下一个城市的概率×(其他人走到下一个城市的概率+第i个人一定会走到下一个城市)经过i城市的人数hi,x+1
即
ps×pi×(pn−pi+1)cnthi,x+1
时间复杂度: O(nm2m)
代码
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<ctime>
#include<utility>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
double p[20];
double f[20][20];
double h[20][20];
int main()
{
// freopen("b.in","r",stdin);
int n,m;
scanf("%d%d",&m,&n);
int i;
for(i=1;i<=m;i++)
scanf("%lf",&p[i]);
int j;
for(i=1;i<=m;i++)
{
f[i][1]=1;
for(j=2;j<=n;j++)
f[i][j]=f[i][j-1]*p[i];
}
double ans=0;
for(i=1;i<=m;i++)
for(j=1;j<=n;j++)
{
scanf("%lf",&h[i][j]);
ans+=f[i][j]*h[i][j];
}
int s;
for(i=1;i<=n-1;i++)
for(s=1;s<(1<<m);s++)
{
double ps=1,sum=0,pn=0;
int cnt=0;
for(j=1;j<=m;j++)
if(s&(1<<(j-1)))
{
ps*=f[j][i];
cnt++;
pn+=p[j];
}
else
ps*=1-f[j][i];
for(j=1;j<=m;j++)
if(s&(1<<(j-1)))
sum+=p[j]*h[j][i+1]*(pn-p[j]+1);
ans+=ps*sum/cnt;
}
printf("%.10lf\n",ans);
return 0;
}