题意:2^n支球队按照竞赛图踢足球,给你任意两支球队相互之间踢赢的概率,求最后那支球队最可能夺冠。
题解:dp[j][i]代表第j支球队通过第i场比赛的概率,然后dp[j][i]=sum(dp[j][i-1]*dp[j+k][i-1]*p[j][j+k]),k是它这一场可能面对的对手,实际上就是它上一场比赛的第一支队伍+2^(i-1)一直到+2^i。
View Code
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 using namespace std; 5 double p[(1<<7)+3][(1<<7)+3]; 6 double dp[(1<<7)+3][10]; 7 int main() 8 { 9 int n; 10 while(scanf("%d",&n)&&n!=-1) 11 { 12 int num=1<<n; 13 memset(dp,0,sizeof(dp)); 14 for(int i=1; i<=num; dp[i][0]=1.0,i++) 15 for(int j=1; j<=num; j++) 16 scanf("%lf",&p[i][j]); 17 for(int i=1; i<=n; i++) 18 { 19 int ce=1<<(i-1),ne=1<<i; 20 for(int j=1; j<=num; j+=ne) 21 { 22 for(int t=0; t<ce; t++) 23 { 24 for(int k=ce; k<ne; k++) 25 { 26 dp[j+t][i]+=dp[j+t][i-1]*dp[j+k][i-1]*p[j+t][j+k]; 27 dp[j+k][i]+=dp[j+t][i-1]*dp[j+k][i-1]*p[j+k][j+t]; 28 } 29 } 30 } 31 } 32 int id=0; 33 double ans=0; 34 for(int i=1; i<=num; i++) 35 { 36 if(dp[i][n]>ans) 37 ans=dp[id=i][n]; 38 } 39 printf("%d\n",id); 40 } 41 return 0; 42 }