计算概率的题目。模拟对应的过程,然后按照概率公式计算主要是在计算每一轮的每个人的可能的对手的时候比较麻烦。我们先计算出,每个人所属的组,然后计算出每个人与其相邻的组,也就是本轮所需要的PK的对手的组,然后对需要PK组一一计算概率。
/*
author : csuchenan
prog : POJ 3071
Algorithm: Probability DP
csuchenan 3071 Accepted 728K 94MS C++ 1217B
*/
#include <cstdio>
#include <cstring>
const int maxn = 1<<9 ;
double pr[maxn][maxn] ;
double dp[10][maxn] ;
int n ;
int main(){
freopen("test.in" ,"r" , stdin) ;
while(scanf("%d" , &n) , n != -1){
//read
for(int i = 0 ; i < (1<<n) ; i ++){
for(int j = 0 ; j < (1<<n) ; j ++){
scanf("%lf" , &pr[i][j]) ;
}
}
//init
for(int i = 0 ; i <= (1<<n) ; i ++){
dp[0][i] = 1 ;
}
//caculate
for(int i = 1 ; i <= n ; i ++){
for(int j = 0 ; j < (1<<n) ; j ++){
int t = j/(1<<(i - 1)) ;
dp[i][j] = 0 ;
t = t ^ 1 ;
// the against of the j
for(int k = t * (1<<(i - 1)) ; k < t * (1<<(i - 1)) + (1<<(i - 1)) ; k ++){
dp[i][j] += dp[i - 1][j] * pr[j][k] * dp[i - 1][k] ;
}
}
}
//get max
int ans ;
double temp = 0 ;
for(int i = 0 ; i < (1<<n) ; i ++){
if(dp[n][i] > temp){
ans = i ;
temp = dp[n][i] ;
}
}
printf("%d\n" , ans + 1) ;
}
return 0 ;
}