http://poj.org/problem?id=3071 (题目链接)
题意
${2^n}$个队伍打淘汰赛,输的被淘汰。第1个队打第2个队,第3个队打第4个队······给出第i个队伍打赢第j个队伍的概率p[i][j],求哪只队伍获得冠军的可能性最大
Solution
很简单,想到一个dp方程:${f_{i,j}}$表示第i轮,j胜出的概率。转移很显然:
$${f_{i,j}=f_{i-1,j}×f_{i-1,k}×p_{j,k}}$$
代码
// poj3071 #include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<cmath> #define LL long long #define inf 1<<30 #define Pi acos(-1.0) #define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout); using namespace std; int bin[20],n,m; double f[1000][1000],p[1000][1000]; int main() { bin[0]=1;for (int i=1;i<=10;i++) bin[i]=bin[i-1]<<1; while (scanf("%d",&n) && n>0) { int m=1<<n; for (int i=1;i<=m;i++) for (int j=1;j<=m;j++) scanf("%lf",&p[i][j]); for (int i=1;i<=m;i++) f[0][i]=1; for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) { int s=(j-1)/bin[i-1]+1; f[i][j]=0; if (s&1) { for (int k=s*bin[i-1]+1;k<=(s+1)*bin[i-1];k++) f[i][j]+=f[i-1][j]*f[i-1][k]*p[j][k]; } else { for (int k=(s-2)*bin[i-1]+1;k<=(s-1)*bin[i-1];k++) f[i][j]+=f[i-1][j]*f[i-1][k]*p[j][k]; } } int ans=1; for (int i=2;i<=m;i++) if (f[n][ans]<f[n][i]) ans=i; printf("%d\n",ans); } return 0; }