G. Gnoll Hypothesis(简单概率)
Posted issue是fw
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了G. Gnoll Hypothesis(简单概率)相关的知识,希望对你有一定的参考价值。
题意
有 n 只怪物,每只怪物的生成概率为 pi 。只有 k 只怪物会生成(任意 k只),不生成的怪物原本的生成概率将会向后转移给下一只会可能生成的怪物,如果是第n个那么就转移给第一个,问最终每个怪物生成的概率是多少
考虑计算虫子 i i i的生成概率
当 j < i j<i j<i时,只有 [ j , i − 1 ] [j,i-1] [j,i−1]的怪物都没有生成且 i i i被生成时, j j j的初始生成概率才会转移给 i i i
当 j > i j>i j>i时,只有 [ j , n ] [j,n] [j,n]和 [ 1 , i − 1 ] [1,i-1] [1,i−1]都没生成且 j j j生成时,生成概率才会转移给 i i i
因此我们预处理连续 s s s个怪物没有被生成的概率为 f [ s ] f[s] f[s]
令 f [ 0 ] = 1 f[0]=1 f[0]=1
显然 f [ s ] = f [ s − 1 ] ∗ n − ( s − 1 ) − k n − ( s − 1 ) f[s]=f[s-1]*\\frac{n-(s-1)-k}{n-(s-1)} f[s]=f[s−1]∗n−(s−1)n−(s−1)−k
在存在 s s s只怪物未生成时,第 i i i只怪物生成的概率是 k n − s \\frac{k}{n-s} n−sk,所以可以枚举每只怪物给第 i i i只怪物造成的贡献累加
#include <bits/stdc++.h>
using namespace std;
const int maxn = 3e5+10;
double f[maxn],p[maxn],ans[maxn];
int n,k;
int main()
{
cin >> n >> k;
for(int i=1;i<=n;i++) cin >> p[i];
f[0] = 1;
for(int i=1;i<=n-k;i++) f[i] = f[i-1]*( n-i+1-k )/(n-i+1);
for(int i=1;i<=n;i++)
{
ans[i] = p[i]*k/n;
for(int j=1;j<=n;j++)
{
if( i==j ) continue;
int z;
if( j<i ) z = i-j;
else z = n-j+1+( i-1 );
if( z>n-k ) continue;
ans[i] += p[j]*f[z]*k/( n-z );
}
}
for(int i=1;i<=n;i++) printf("%.10lf ",ans[i] );
}
以上是关于G. Gnoll Hypothesis(简单概率)的主要内容,如果未能解决你的问题,请参考以下文章