转自:cxlove
题目:有2^n个队,相邻的两两打淘汰赛,,求最后哪个队夺冠的概率最大
dp[i][j]表示第i轮的时候,第j去支队伍赢的概率。
那么dp[i][j]的前提就是i-1轮的时候,j是赢的,而且第i轮赢了对方
接下来就是找到第i轮的时候,他的可能队手
通过二进制可以发现规律,所有高位是一样的,第i位刚好相反,所以用位运算可以巧妙解决,见代码
dp[i][j]=sigma(dp[i-1][j]*dp[i-1][k]*p[j][k])
1 #include<stdio.h> 2 #include<iostream> 3 #include<algorithm> 4 #include<string.h> 5 using namespace std; 6 double dp[8][200];//dp[i][j]表示在第i场比赛中j胜出的概率 7 double p[200][200]; 8 int main() 9 { 10 int n; 11 #ifndef ONLINE_JUDGE 12 freopen("1.in","r",stdin); 13 #endif 14 while(scanf("%d",&n)!=EOF) 15 { 16 if(n==-1)break; 17 memset(dp,0,sizeof(dp)); 18 for(int i=0;i<(1<<n);i++) 19 for(int j=0;j<(1<<n);j++) 20 scanf("%lf",&p[i][j]); 21 for(int i=0;i<(1<<n);i++) dp[0][i]=1; 22 for(int i=1;i<=n;i++){ 23 for(int j=0;j<(1<<n);j++){ 24 for(int k=0;k<(1<<n);k++){ 25 if(((j>>(i-1))^1)==(k>>(i-1))) 26 dp[i][j]+=dp[i-1][k]*dp[i-1][j]*p[j][k]; 27 } 28 } 29 } 30 int ans; 31 double temp=0; 32 for(int i=0;i<(1<<n);i++) 33 { 34 if(dp[n][i]>temp) 35 { 36 ans=i; 37 temp=dp[n][i]; 38 } 39 } 40 printf("%d ",ans+1); 41 } 42 return 0; 43 }