poj3071 Football

/*
概率dp,位運算
dp[i][j]表示第i輪第j個人贏的概率
dp[i][j]=dp[i-1][j]*sum(dp[i-1][k]*p[j][k])k是第j個人在第i輪遇到的人
可以發現第j個人和第k個人的第i位剛好相反,第i位以下是一樣的,所以可以用位運算
*/
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
#define N 20
double p[N][N];
double dp[10][10];
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        if(n==-1) break;
        for(int i=0;i<(1<<n);i++)
            for(int j=0;j<(1<<n);j++)
                scanf("%lf",&p[i][j]);

        memset(dp,0,sizeof(dp));
        for(int i=0;i<(1<<n);i++)
            dp[0][i]=1;

        for(int i=1;i<=n;i++)
        {
            for(int j=0;j<(1<<n);j++)
            {
                for(int k=0;k<(1<<n);k++)
                    if(((j>>(i-1))^1)==(k>>(i-1)))
                        dp[i][j]+=dp[i-1][j]*dp[i-1][k]*p[j][k];
            }
        }

        double ans=0;
        int id=-1;
        for(int i=0;i<(1<<n);i++)
        {
            if(dp[n][i]>ans)
            {
                ans=dp[n][i];
                id=i+1;
            }
        }
        printf("%d\n",id);
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章