SWUST OJ NBA Finals(0649)
NBA Finals(0649)
1 #include<iostream> 2 #include<cstring> 3 using namespace std; 4 int main() 5 { 6 double P[205][205],p; 7 int i,j,n; 8 while(cin>>n>>p) 9 { 10 for(i=1;i<=n;i++) 11 { 12 P[i][0]=0; 13 P[0][i]=1; 14 } 15 for(i=1;i<=n;i++) 16 { 17 for(j=1;j<=n;j++) 18 { 19 P[i][j]=P[i-1][j]*p+P[i][j-1]*(1-p); 20 } 21 } 22 cout<<P[n][n]<<endl;//cout<<P[n-3][n-3]<<endl 23 } 24 return 0; 25 }
SWUST OJ数据有误,http://acm.swust.edu.cn/problem/649/,AC代码:cout<<P[n-3][n-3]<<endl,由于BUG,只能用C++写,用C提交WA。
AHU 0J:http://icpc.ahu.edu.cn/OJ/Problem.aspx?id=294,反而用C++提交,WA。
注:这题输入 n 代表该比赛是 2*n+1 场 n 胜制,输入 7 即 15 场 7胜制。不可以用组合数去做,数据太大了。
用dp去做,P[i][j]的含义是:当A队(湖人队)还有 i 场比赛需要赢,才能夺得冠军,B队(凯尔特人队)还有 j 场比赛需要赢,才能夺得冠军时,A队(湖人队)获得冠军的概率,所以边界 P[i][0]=0 (1<=i<=n)(B队已经夺冠了),P[0][i]=1 (1<=i<=n)(A队已经夺冠了),要求的输出即是 P[n][n](带入上述P[i][j]去理解)。
关于状态转移方程 P[i][j]=P[i-1][j]*p+P[i][j-1]*(1-p) 说明如下:
P[i-1][j]*p( P[i][j-1]*(1-p) ),这里是乘。表面上看,P[i-1][j]相比于P[i][j]多一个胜场,但不能凭感觉地依靠乘法原理,得到 P[i][j]*p=P[i-1][j] ( P[i][j]=P[i-1][j]/p ),原因是,P[i-1][j]相比于P[i][j]在计算时少考虑了这个胜场,P[i-1][j ]的值是大于 P[i][j]的,所以应用 P[i-1][j] 乘以 p,将这个胜场考虑进去。