您的位置:首页 > 其它

概率专题·期望

2016-01-02 00:40 477 查看
uva 11021 Tribbles

UVA 11722 Joining with Friend

UVA 11427 Expect the Expected

UVA 11762 Race to 1

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

UVA 11346 Probability

UVA 11637 Garbage Remembering Exam

UVA 11605 Lights inside a 3d Grid

UVA 10491 Cows and Cars

UVA 1413 Game

UVA 1498 Activation

uva 11021 Tribbles

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

fi=p0+p1fi−1+p2fi−22+...+pn−1fi−1n−1f_i=p_0+p_1f_{i-1}+p_2{f_{i-2}}^2 + ... + p_{n-1}{f_{i-1}}^{n-1}

#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(1−Q)Q+3(1−Q)2Q+...Ex=Q+2(1-Q)Q+3(1-Q)^2Q+...

高中数学作差法可得Ex=1/QEx=1/Q

计算Q可以dp,dpi,j表示前i天赢j局时,最后‘垂头丧气′的概率dp_{i,j}表示前i天赢j局时,最后‘垂头丧气’的概率

dp[i,j]=dp[i−1,j](1−p)+dp[i−1,j−1]p(j/i≤p)dp[i,j]=dp[i-1,j](1-p)+dp[i-1,j-1]p \quad (j/i \le p)

#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
[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
=(ll)1<<(ll)n;
if (fabs(1-t)<eps) {
cout<<dp
<<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
=1;
For(i,2*k)
{
p
=p
*(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和

根据

{(1−p+p)n=C0npn+C1n−1(1−p)pn−1+...+Cnn(1−p)n(1−p−p)n=(−1)nC0npn+(−1)n−1C1n−1(1−p)pn−1+...+Cnn(1−p)n\cases{ {(1-p+p)^n=C_n^0p^n + C_{n-1}^1(1-p)p^{n-1}+...+C_{n}^n(1-p)^n} \\ { (1-p-p)^n }=(-1)^nC_n^0p^n + (-1)^{n-1}C_{n-1}^1(1-p)p^{n-1}+...+C_{n}^n(1-p)^n }

可以求出C1n(1−p)n−1p+C3n(1−p)n−3p3+...+Ckn(1−p)n−kpk∣k是奇数C_n^1(1-p)^{n-1}p+C_{n}^3(1-p)^{n-3}p^3+...+C_n^k(1-p)^{n-k}p^k \mid \quad k \text{是奇数}

#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,jf_{i,j}表示队列有i人排第j时“倒霉”的机率,先解方程求出fi,if_{i,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
[M]<<endl;
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: