概率专题·期望

uva 11021 Tribbles

k只麻球,每活一天就会死亡,但第二天可能会生一些麻球,具体说来,生i个麻球的概率为pi ,求m天后所有麻球都死亡的概率
fi=p0+p1fi1+p2fi22+...+pn1fi1n1

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<iostream>
#include<cmath>
#include<cctype>
#include<ctime>
#include<iomanip> 
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=next[p])  
#define Lson (x<<1)
#define Rson ((x<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int> 
typedef long long ll;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
#define MAXN (1000+10)
int T,n,k,m;
double p[MAXN],f[MAXN];
int main()
{
//  freopen("uva11021.in","r",stdin);
//  freopen(".out","w",stdout);

    T=read();
    For(kcase,T) {
        n=read(),k=read(),m=read();
        Rep(i,n) cin>>p[i];
        f[0]=0; f[1]=p[0];
        Fork(i,2,m) {
            f[i]=0;
            Rep(j,n) f[i]+=p[j]*pow(f[i-1],j);                      
        }
        printf("Case #%d: %.7lf\n",kcase,pow(f[m],k));      
    }
    return 0;
}

UVA 11722 Joining with Friend

题意:假设你会在时间区间[t1,t2]中的任意时刻以相同的概率到达火车站,你朋友则在[s1,s2]中的任意时刻以相同的概率到达火车站,你们在到达后停留w分钟,问你们会面的概率。若存在一个时刻你们同时在火车站视为一定会面。
题解:概率空间是坐标系中的一个矩形,分情况讨论算面积。

#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define pb push_back
#define mp make_pair 
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
ld t1,t2,s1,s2,w;
int main()
{
//  freopen("uva11722.in","r",stdin);
//  freopen(".out","w",stdout);

    int T=read();
    For(kcase,T) {
        cin>>t1>>t2>>s1>>s2>>w;
        if (s2-t2>s1-t1) swap(t1,s1),swap(t2,s2);
        ld a[5]={0,s1-t2,s2-t2,s1-t1,s2-t1};
        ld S=(t2-t1)*(s2-s1),p=0;

        if (-w<a[1]) {
        } else if (-w<a[2]) {
            p+=pow(t2-w-s1,2)/2;    
        } else if (-w<a[3]) {
            p+=(t2-s1-w+t2-s2-w)*(s2-s1)/2;
        } else if (-w<a[4]) {
            p+=S-pow(s2+w-t1,2)/2;
        } else p+=S;
        if (w<a[1]) {
            p+=S;
        } else if (w<a[2]) {
            p+=S-(t2+w-s1)*(t2+w-s1) /2;    
        } else if (w<a[3]) {
            p+=S- (t2-s1+w+t2-s2+w)*(s2-s1)/2;
        } else if (w<a[4]) {
            p+=pow(s2-w-t1,2)/2;
        } 
        printf("Case #%d: ",kcase);
        cout<<(S-p)/S<<endl;
    }

    return 0;
}

UVA 11427 Expect the Expected

题意:每天晚上你会玩牌。第一把赢了就去睡觉,输了继续。你每一把赢的概率是p,当你赢的比例严格大于p时,才会去睡觉。但是你一个晚上最多玩n把游戏,如果哪天获胜比例一直没有大于p,你以后再也不玩了。求玩游戏天数的期望。

假设单独一天获胜概率为Q
Ex=Q+2(1Q)Q+3(1Q)2Q+...
高中数学作差法可得 Ex=1/Q

计算Q可以dp, dpi,jij
dp[i,j]=dp[i1,j](1p)+dp[i1,j1]p(j/ip)

#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define pb push_back
#define mp make_pair 
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
typedef long long ll;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
const int maxn = 100 + 10;
int n;
double dp[maxn][maxn];
int main()
{
//  freopen("uva11427.in","r",stdin);
//  freopen(".out","w",stdout);

    int T=read();
    For(kcase,T) {
        int a,b;
        scanf("%d/%d %d",&a,&b,&n);
        double p=(double)a/b;

        MEM(dp) dp[0][0]=1;
        For(i,n)
            Rep(j,i) 
            {
                if ((double)j/i>p) break;
                dp[i][j]=dp[i-1][j]*(1-p)+( j ? dp[i-1][j-1]*p : 0 ); 
            } 
        double ans=0;
        Rep(j,n) ans+=dp[n][j];
        printf("Case #%d: %d\n",kcase,(int)(1/ans)); 


    }


    return 0;
}

UVA 11762 Race to 1

其实直接用马尔可夫过程就好

#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define pb push_back
#define mp make_pair 
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
typedef long long ll;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
const int MAXN = (1000000+10);
int primes[MAXN],size=0;
bool b[MAXN]={0};
void make_prime() {
    int n=MAXN-10;
    Fork(i,2,n) {
        if (!b[i]) primes[++size]=i;
        For(j,size) {
            if (i*primes[j]>n) break;
            b[i*primes[j]]=1;
            if (i%primes[j]==0) break;
        }
    }
}

double dp[MAXN]={0};
bool vis[MAXN]={0,1};
double calc(int x) {
    if (vis[x]) return dp[x];
    dp[x]=1; 
    int siz=0,t=0;
    double c=0;
    for(int i=1;primes[i]<=x&&i<=size;++i) {
        ++siz;
        if (x%primes[i]==0) ++t,c+=calc(x/primes[i]);
    }
    return dp[x] = (c+siz)/t;   
}


int main()
{
//  freopen("uva11762.in","r",stdin);
//  freopen(".out","w",stdout);
    make_prime();
    int T=read();
    For(kcase,T) {
        double ans=calc(read());
        printf("Case %d: %.8lf\n",kcase,ans);
    }


    return 0;
}

UVA 10491 So you want to be a 2n-aire?

很容易搞错的是,每次拿到题目后’我’马上知道答对概率,要根据这个概率决策的。

#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define pb push_back
#define mp make_pair 
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define eps (1e-9)
#define SI(a) ((a).size())
typedef long long ll;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
int n;
double t,p,dp[50];
void work() {
    dp[n]=(ll)1<<(ll)n;
    if (fabs(1-t)<eps) {
        cout<<dp[n]<<endl; 
        return;
    }
    RepD(i,n-1) {
        double p2=((ll)(1<<(ll)i));
        double f=p2 / dp[i+1];
        if (f<=t) dp[i]=p*dp[i+1];
        else dp[i] = ( (f-t)*p2 + (1-f)*(f+1) /2*dp[i+1] ) / (1-t); 
    }
    cout<<dp[0]<<endl;
}
int main()
{
//  freopen("uva10900.in","r",stdin);
//  freopen(".out","w",stdout);
    cout<<setiosflags(ios::fixed)<<setprecision(3);
    while(cin>>n>>t && n) { 
        p=(1+t)/2;
        work();
    }
    return 0;
}

UVA 11346 Probability

积分求面积,SB题

#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define pb push_back
#define mp make_pair 
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
typedef long long ll;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
int main()
{
//  freopen("uva11346.in","r",stdin);
    int T=read();
    double a,b,S;
    while(cin>>a>>b>>S) {
        if (a*b<=S) {
            puts("0.000000%");
        } else if (S<1e-7) {
            puts("100.000000%");
        }else {
            printf("%.6lf%\n",100-(1+log(a)-log(S/b))*S/a/b*100);
        }
    }   


    return 0;
}

UVA 11637 Garbage Remembering Exam

期望具有线性性质,原题可以拆成每个单词无效无效概率的和,取反计算有效概率,线状排列中与第i个有效的概率为与在线排列中其所有距离不超过k的在都在环中超过k个的概率,暴力统计

#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define pb push_back
#define mp make_pair 
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
typedef long long ll;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
const int MAXN = 100000 + 10;
int k,n;
double p[MAXN];
double solve(int n,int k) {
//  {2*k+1..n-1-2k}
    MEM(p) 
    int x=2*k+1;
    p[n]=1;
    For(i,2*k)
    {
        p[n]=p[n]*(n-2*k+i)/(n-2*k-1+i);
    }
    ForkD(X,x,n) {
        p[X-1]=p[X]*(X-2*k)/X; 
    }   
    double ans=0;
    For(i,n) {
        int len=n-(min(i+k,n)-max(i-k,1)+1);
        ans+=1-p[len];
    } 
    return ans;
}
int main()
{
//  freopen("uva11637.in","r",stdin);
//  freopen(".out","w",stdout);

    int kcase=1;
    while (cin>>n>>k && n && k) {
        double ans=0;
        if (n==1) ans=0;
        else if (n-1-2*k>0) {
            ans=solve(n,k);
        } else {
            ans=n;
        }   
        printf("Case %d: %.4lf\n",kcase++,ans);
    }
    return 0;
}

UVA 11605 Lights inside a 3d Grid

用线性期望转成所有灯开的概率,由于这题是用xor和
根据
{(1p+p)n=C0npn+C1n1(1p)pn1+...+Cnn(1p)n(1pp)n=(1)nC0npn+(1)n1C1n1(1p)pn1+...+Cnn(1p)n
可以求出 C1n(1p)n1p+C3n(1p)n3p3+...+Ckn(1p)nkpkk

#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define pb push_back
#define mp make_pair 
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
typedef long long ll;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
int M,N,P,K;
void calc(int i,int j,int k) {

}
int main()
{
//  freopen("uva11605.in","r",stdin);
//  freopen(".out","w",stdout);

    int T=read();
    For(kcase,T) {
        double ans=0;
        cin>>N>>M>>P>>K;
        For(i,N)
            For(j,M)
                For(k,P) {
                    double p=(2.0*i*(N-i+1)-1)*(2*j*(M-j+1)-1)*(2*k*(P-k+1)-1)/(double)N/N/M/M/P/P;
                    ans+=1-pow(1.0-2*p,K);
                }
        printf("Case %d: %.10lf\n",kcase,ans/2);
    }

    return 0;
}

UVA 10491 Cows and Cars

注意所有门是一次打开的

#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define pb push_back
#define mp make_pair 
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
typedef long long ll;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
int main()
{
//  freopen("uva11181.in","r",stdin);
//  freopen(".out","w",stdout);

    double a,b,c;
    while(cin>>a>>b>>c) {
        cout<<setiosflags(ios::fixed)<<setprecision(5);
        cout<< (a*b+b*(b-1))/(a+b)/(a+b-c-1)<<endl;
    }

    return 0;
}

UVA 1413 Game

卡精度问题,首先可以用区间dp算出一个某个区间的某侧人拿球时传左,右的概率,然后考虑第k个人拿球时,出现某个区间某侧人拿球的期望,只要n-1个人拿球了,后面无论如何都是n赢

#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define pb push_back
#define mp make_pair 
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
const int MAXN = 50 +10;
int n,k;
double p[MAXN]; 
const int L = 0, R = 1;
ld f[MAXN][MAXN][2][2]; // [left,Right,Ball,Excepted Direction]

ld dp[MAXN][MAXN][2]; // P[Left,Right,Excepted Direction]

int main()
{
//  freopen("uva1413.in","r",stdin);
//  freopen(".out","w",stdout);

    while(scanf("%d%d",&n,&k)==2) {
        MEM(p) MEM(f) MEM(dp)

        For(i,n-1) scanf("%lf",&p[i]);

        For(i,n-1) {
            f[i][i][L][L]=f[i][i][R][L]= 1 - p[i];
            f[i][i][L][R]=f[i][i][R][R]= p[i];
        }
        // 用等比数列算出的公式 :在区间[I,J],球在k端时,从l端出去的概率  
        For(d,n) {
            For(i,n-d-1) {
                int j=i+d;
                f[i][j][L][L]= (1-p[i]) / ( 1 - p[i] + p[i]*f[i+1][j][L][R] );
                f[i][j][L][R]=  p[i]*f[i+1][j][L][R] / ( 1 - p[i] + p[i]*f[i+1][j][L][R] ); //如果直接用上面的概率减会卡精度
                f[i][j][R][R]= (p[j]) / ( p[j] + (1 - p[j]) * f[i][j-1][R][L] );
                f[i][j][R][L]=  ( (1 - p[j]) * f[i][j-1][R][L]) / ( p[j] + (1 - p[j]) * f[i][j-1][R][L] );
            }
        }
        // 在区间[I,J],球在k端的概率 
        dp[k][k][R]=1;

        For(d,n-1) {
            For(i,n-d-1) {

                int j=i+d;
                dp[i][j][L] = dp[i+1][j][L] * f[i+1][j][L][L] + dp[i+1][j][R] * f[i+1][j][R][L];
                dp[i][j][R] = dp[i][j-1][L] * f[i][j-1][L][R] + dp[i][j-1][R] * f[i][j-1][R][R];
            }
        }

        double ans = dp[1][n-1][L] + dp[1][n-1][R];
        cout<<setiosflags(ios::fixed)<<setprecision(10);
        cout<<ans<<endl;


    }

    return 0;
}

UVA 1498 Activation

排队,注意各种特判, fi,j 表示队列有i人排第j时“倒霉”的机率,先解方程求出 fi,i 递推。

#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define pb push_back
#define mp make_pair 
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
typedef long long ll;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
const int MAXN = (2000+10); 
int N,M,K;
double p1,p2,p3,p4;
double f[MAXN][MAXN];  
void prework() {
    For(i,N) {
        double k=p2/(1-p1);
        f[i][i]=0;
        double k2=pow(k,i-1),b2=0;
        Fork(j,2,i) b2=b2*k+(p3*f[i-1][j-1]+p4 * (bool)(j<=K) )/ (1-p1);
        f[i][i]= (k2 * p4 / (1-p1) + b2 ) / ( 1 - k2 * p2 / (1 - p1) ) ;
        f[i][1]=( p2 * f[i][i] + p4 ) / ( 1 - p1 );
        Fork(j,2,i-1) {
            f[i][j] = (p2 * f[i][j-1] + p3 * f[i-1][j-1] + p4 * (j<=K) ) / (1-p1) ;
        }

    }
}

int main()
{
//  freopen("uva1498.in","r",stdin);
//  freopen(".out","w",stdout);

    while(cin>>N>>M>>K) {
        cin>>p1>>p2>>p3>>p4;
        if (p3 == 0 && p4 == 0 || p1 == 1 || p3 == 1 || p2 == 1 ) {
            puts("0.00000"); continue;
        } 
        MEM(f)
        prework();
        cout<<setiosflags(ios::fixed)<<setprecision(5);
        cout<<f[N][M]<<endl; 
    }


    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值