我想大声告诉你

来源:互联网 发布:常见自动控制算法 编辑:程序博客网 时间:2024/04/28 19:48

我想大声告诉你

Description

    有n个人,每次先选一个人出局,然后攻击剩下的人,打死的概率为p。    因为每个人的概率是相同的,求一个人顶了k(0..n-1)次攻击才死的概率。    答案模258280327

Sample Input

    2    3 40 100    9 32 1049

Sample Output

    172186885 92980918 16529941    229582513 163885050 39458156 102374877 116777758 216371874 55544199 95860736 8136787 

Solution

这题可以转换成有n个人,依次让每个人出局,然后攻击后面的人。

可以用Dp来做。用f[i,j]表示到当前第i个人时,第i到n的人被攻击j次(可能死了)的概率。
这个Dp也可以理解为到当前第i个人时,前面还活着j个人的概率,因为每次有一个人活着才会让他出局,所以会马上攻击后面的人,那么后面的人被攻击次数是和前面的人还活着的次数相等的。

f[i,j]=f[i-1,j-1] * (1-p)^(j-1)+f[i-1,j] * (1-(1-p)^j);

假如当前到i,前面活着j个人。

在i-1时前面活着j-1个人——>说明第i-1个人没死,他的概率是(1-p)^(j-1)

在i-1时前面还活着j个人——>说明第i-1死了,他的概率是(1-(1-p)^j)【1-活着的概率=死了的概率】

Code

#include<iostream>#include<cstring>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#define fo(i,a,b) for(i=a;i<=b;i++)#define ll long longconst int mo=258280327;using namespace std;int i,j,k,t,n,m,lll;int yi,er,p,q,ans;ll f[2005][2005],yu[2005],l;ll qsm(ll x,ll y){    int z=1;    while(y!=0){        if(y&1==1)z=z*x%mo;        x=x*x%mo;        y=y/2;    }    return z;}ll chu(ll x,ll y){    ll z=0;    z=(qsm(y,mo-2)*x)%mo;    return z;}int main(){    scanf("%d",&t);    fo(lll,1,t){        scanf("%d%lld%lld",&n,&p,&q);        memset(f,0,sizeof(f));        yu[0]=1;        fo(i,1,n) yu[i]=yu[i-1]*chu(q-p,q)%mo;        f[1][0]=1;        fo(i,2,n){            fo(j,1,i-1){                f[i][j]=(f[i-1][j-1]*yu[j-1]%mo+f[i-1][j]*((1-yu[j]+mo)%mo)%mo)%mo;            }        }        fo(i,0,n-1){            l=0;            fo(j,1,n) l=(l+f[j][i]*yu[i]%mo)%mo;            l=chu(l,n)%mo;            printf("%lld ",l);        }        printf("\n");    }}
1 0
原创粉丝点击