分析:
实际上题目中已经给出了计算方式
P(2wins)=P(2beats1)P(3beats4)P(2beats3)+P(2beats1)P(4beats3)P(2beats4)
P
(
2
w
i
n
s
)
=
P
(
2
b
e
a
t
s
1
)
P
(
3
b
e
a
t
s
4
)
P
(
2
b
e
a
t
s
3
)
+
P
(
2
b
e
a
t
s
1
)
P
(
4
b
e
a
t
s
3
)
P
(
2
b
e
a
t
s
4
)
=p2,1p3,4p2,3+p2,1p4,3p2,4
=
p
2
,
1
p
3
,
4
p
2
,
3
+
p
2
,
1
p
4
,
3
p
2
,
4
=0.9⋅0.6⋅0.4+0.9⋅0.4⋅0.5=0.396
=
0.9
·
0.6
·
0.4
+
0.9
·
0.4
·
0.5
=
0.396
设
f[i][j]
f
[
i
]
[
j
]
,表示第
i
i
轮,队获胜的概率
第
i
i
轮,比赛会在长度为的序列内进行
前
2i−1
2
i
−
1
支队伍会与后
2i−1
2
i
−
1
支队伍比赛
f[i][x]=∑f[i−1][x]∗f[i−1][y]∗p[x][y[
f
[
i
]
[
x
]
=
∑
f
[
i
−
1
]
[
x
]
∗
f
[
i
−
1
]
[
y
]
∗
p
[
x
]
[
y
[
直接转移即可
tip
不要忘了初始化
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const double eps=1e-8;
const int N=130;
int n;
double p[N][N],f[10][N];
int main()
{
while (scanf("%d",&n)!=EOF&&n!=-1) {
int tot=1<<n;
for (int i=1;i<=n;i++)
for (int j=1;j<=tot;j++) f[i][j]=0.0;
for (int i=1;i<=tot;i++)
for (int j=1;j<=tot;j++)
scanf("%lf",&p[i][j]);
for (int i=1;i<=tot;i++) f[1][i]=p[i][(i&1)? i+1:i-1];
for (int i=2;i<=n;i++) {
int m=1<<(i-1);
for (int j=1;j<=tot;j+=(1<<i))
for (int k=j;k<j+m;k++)
for (int s=j+m;s<j+2*m;s++) {
f[i][k]+=f[i-1][k]*f[i-1][s]*p[k][s];
f[i][s]+=f[i-1][s]*f[i-1][k]*p[s][k];
}
}
int ans;
double mx=0;
for (int i=1;i<=tot;i++)
if (f[n][i]-mx>eps) mx=f[n][i],ans=i;
printf("%d\n",ans);
}
return 0;
}