[题解]UVA11021 Tribles
我们一开始有\(k\)只生物,这是很难搞的,所以可以先考虑一开始只有1只生物,
设\(p[i]\)表示一开始有\(1\)只生物,第\(i\)天所有生物死光光的概率,
求出\(p[m]\)后,\(ans = p[m]^{k}\),
为什么呢,就是乘法公式哦,也可以感谢理解下,把一开始的\(k\)生物一只一只分开,它们和它们的子孙后代就是一个个互不干涉的家族,总共有\(k\)个家族,在第\(m\)天所有的\(k\)个家族都灭门的概率不就是\(p[m]^k\)吗?滑稽(
所以现在我们只要求\(p[m]\),先给出式子:
\[s[i] = \sum_{j=0}^{n-1}p[j]*s[i-1]^j
\]
来理解下,假如昨天存活的生物生了\(j\)个后代(这\(j\)个后代是独立的,互不干涉),每个后代在今天肯定会,死的概率就是它昨天出生的概率\(s[i-1]\),所以\(j\)个全死的概率就是\(s[i-1]^j\),枚举\(j\)相加就好
#include <cstdio>
#include <cstring>
typedef double db;
const int N = 1e3 + 30;
int T, n, m, k, cnt;
db p[N], s[N];
db POW(db t, int num)
{
db ans = 1;
while (num)
{
if (num & 1) ans *= t;
t *= t, num >>= 1;
}
return ans;
}
int main()
{
scanf ("%d", &T);
while (T--)
{
scanf ("%d%d%d", &n, &k, &m);
for (int i = 0; i < n; ++i) scanf ("%lf", &p[i]);
s[1] = p[0];
for (int i = 2; i <= m; ++i)
{
s[i] = 0;
for (int j = 0; j < n; ++j) s[i] += p[j] * POW(s[i - 1], j);
}
printf ("Case #%d: %.7lf\n", ++cnt, POW(s[m], k));
}
return 0;
}