UVA11021 Tribles 概率dp

题目传送门

题意:开始有$k$只兔子,每只都是活一天就死,每只死前都会有$pi$的概率生出$i$只兔子。求$m$天后兔子死光的概率。

思路: 

  设$f[i]$为一只兔子在第i天死完的概率,那么答案就是$f[m]^k$。

  所以关键是求$f[i]$.

     由全概率公式得

    $f[i]=p0+p1*f[i-1]+p2*f[i-1]^2+...+pn*f[i-1]^n$

  这个式子要怎么理解呢?p0是一只兔子第一天就死完的概率。p1是一只兔子在第一天生出了一只兔子,那么这种情况下在第i天死完的概率就是p1*f[i-1],由于兔子死亡是独立重复时间,所以概率以指数的形式相乘。

  

#pragma GCC optimize (2)
#pragma G++ optimize (2)
#pragma comment(linker, "/STACK:102400000,102400000")
#include<bits/stdc++.h>
#include<unordered_map>
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define dep(i,b,a) for(int i=b;i>=a;--i)
#define clr(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define pii pair<int,int >
using namespace std;
typedef long long ll;
ll rd()
{
    ll x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
const int maxn=1010;
const int inf=0x3f3f3f3f;
int n,m,k,T;
double dp[maxn],f[maxn],p[maxn];
int main(){
    cin>>T;
    int cat=1;
    while(T--){
        cin>>n>>k>>m;
        double res=0;
        rep(i,0,n-1){
            scanf("%lf",&p[i]);
        }
        f[1]=p[0];
        rep(i,2,m){
            f[i]=0;
            rep(j,0,n-1){
                f[i]+=p[j]*pow(f[i-1],j);
            }
        }
        printf("Case #%d: %.7f\n",cat++,pow(f[m],k));
    }
}

猜你喜欢

转载自www.cnblogs.com/mountaink/p/11448620.html