[poj3071]football概率dp
题意:n支队伍两两进行比赛,求最有可能获得冠军的队伍。
解题关键:概率dp,转移方程:$dp[i][j] + = dp[i][j]*dp[i][k]*p[j][k]$表示第$i$回合$j$获胜的概率,原理为全概率公式。
如何判断相邻,通过位运算。
概率dp的过程就像是模拟的过程
复杂度:$O(n{2^n}{2^n})$
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cstdlib> 5 #include<cmath> 6 #include<iostream> 7 using namespace std; 8 typedef long long ll; 9 double arr[130][130]; 10 double dp[130][130]; 11 int main(){ 12 int n; 13 while(scanf("%d",&n)&&(n!=-1)){ 14 memset(dp,0,sizeof dp); 15 int len=1<<n; 16 for(int i=0;i<len;i++){ 17 for(int j=0;j<len;j++){ 18 scanf("%lf",&arr[i][j]); 19 } 20 } 21 for(int i=0;i<len;i++) dp[0][i]=1; 22 23 for(int i=1;i<=n;i++){ 24 for(int j=0;j<len;j++){ 25 for(int k=0;k<len;k++){ 26 if(((j>>(i-1))^1)==k>>(i-1)){ 27 dp[i][j]+=dp[i-1][k]*dp[i-1][j]*arr[j][k]; 28 } 29 } 30 } 31 } 32 33 double ans=0.0; 34 int ind=0; 35 for(int i=0;i<len;i++){ 36 if(dp[n][i]>ans){ 37 ans=dp[n][i]; 38 ind=i; 39 } 40 } 41 printf("%d\n",ind+1); 42 } 43 44 return 0; 45 }