HDU 3076 ssworld VS DDD DP 概率水题

题意:

 A,B掷骰子,对于每一次点数大者胜,平为和,A先胜了m次A赢,B先胜了n次B赢。

题解:

 先将平局情况处理出来,让他们一定要分出胜负,对于每一次p1表示A赢,p2表示B赢,p=1-p1-p2表示平局,所以在不死不休的情况下,A赢的概率为p1+p*p1+p^2*p1+...p^n*p1,n->无穷,即a_win=q1/(1-p);b_win=q2/(1-p);

然后在他们一定会分出胜负的情况下就可以dp了:

   dp[i][j]=dp[i][j-1]*a_win+dp[i-1][j]*b_win;

dp[i][j]表示A胜j次,B胜i次的概率。

#include<iostream> using namespace std; #define MAXN 2005 double dp[MAXN][MAXN]; double a[7],b[7]; double a_win,b_win; double ans; int main() { int n,m,i,j; double p,p1,p2; while(scanf("%d %d",&m,&n)!=EOF) { for(i=1;i<=6;i++) scanf("%lf",&a[i]); for(i=1;i<=6;i++) scanf("%lf",&b[i]); a_win=0; for(i=2;i<=6;i++) { for(j=1;j<=i-1;j++) a_win+=a[i]*b[j]; } b_win=0; for(i=2;i<=6;i++) { for(j=1;j<=i-1;j++) b_win+=b[i]*a[j]; } p1=a_win;p2=b_win;p=1-a_win-b_win; if (p==1) {a_win=0;b_win=0;} else { a_win=p1/(1-p); b_win=p2/(1-p); } for(i=0;i<=n;i++) for(j=0;j<=m;j++) dp[i][j]=0; // cout<<a_win<<' '<<b_win<<endl; dp[0][0]=1; for(j=0;j<=m-1;j++) for(i=0;i<=n;i++) if (i+j!=0) { dp[i][j]=0; if (j>0) dp[i][j]+=dp[i][j-1]*a_win; if (i>0) dp[i][j]+=dp[i-1][j]*b_win; } ans=0; for(i=0;i<=n-1;i++) ans+=dp[i][m-1]*a_win; if (ans>1) ans=1; printf("%.6lf/n",ans); } }

你可能感兴趣的:(HDU 3076 ssworld VS DDD DP 概率水题)