题意:有2^n支球队,按编号顺序比赛,胜者晋级,与上轮的胜者继续按编号顺序比赛...已知每两支球队间输赢的概率,问那支球队最终最有可能夺冠。
思路:概率dp,一轮一轮算,算到最后一轮找出来最大值。
#include <iostream>
#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <iomanip>
#include <cstdlib>
#include <string>
#include <memory.h>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <ctype.h>
#define INF 1000000
#define ll long long
#define min3(a,b,c) min(a,min(b,c))
using namespace std;
int n,num;
double p[130][130];
double ans[10][130];
void findlr(int x,int k,int& l,int& r){
l=1;
r=num;
int time=n-k+1;
while(time--){
int mid=(l+r)/2;
if(time==0){
if(x<=mid){
l=mid+1;
}else{
r=mid;
}
}else{
if(x<=mid){
r=mid;
}else{
l=mid+1;
}
}
}
}
int main(){
while(cin>>n){
if(n==-1)break;
num=1<<n;
for(int i=1;i<=num;i++){
for(int j=1;j<=num;j++){
cin>>p[i][j];
}
}
//init
for(int i=1;i<=num;i++){
ans[0][i]=1.0;
}
//dp
int l,r;
int winner;
double _max=-1.0;
for(int i=1;i<=n;i++){
for(int j=1;j<=num;j++){
findlr(j,i,l,r);
ans[i][j]=0.0;
for(int k=l;k<=r;k++){
ans[i][j]+=ans[i-1][j]*ans[i-1][k]*p[j][k];
}
if(i==n&&ans[i][j]>_max){
_max=ans[i][j];
winner=j;
}
}
}
cout<<winner<<endl;
}
return 0;
}