poj 3071 概论 dp

来源:互联网 发布:大数据分析技术现状 编辑:程序博客网 时间:2024/05/03 12:17
/*题目:http://poj.org/problem?id=3071题意:有(1<<N)个人进行N次比赛,每次比赛都是第i个人和第i+1个人进行,赢的人能进入下一轮,输的人就不能继续比赛,N轮比赛之后,只会有一个人留下来,问谁最终留下来的概率最大。dp[i][j],表示第i轮,第j个人获胜的概论;分析的状态转移方程为:dp[i][j]=sum{dp[i-1][j]*dp[i-1][k]*p[j][k]} (1<<n)>=k>(1<<(i-1));边界条件 dp[0][j]=1;*/#include<iostream>#include<cstdio>#include<algorithm>#include<memory.h>using namespace std;const int maxn=1<<7;double  dp[10][maxn+2],p[maxn+2][maxn+2];int n;int main(){    while(scanf("%d",&n),n!=-1)    {        int i,j,k;        int m=1<<n;        for(i=0; i<=m; i++) dp[0][i]=1.0;        for(i=1; i<=m; i++)        {            for(j=1; j<=m; j++)            {                scanf("%lf",&p[i][j]);            }        }        for(i=1; i<=n; i++)        {            int key=1<<(i-1);            for(j=1; j<=m; j++)            {                dp[i][j]=0.0;                int s , e;                s = 0  ;                int cnt = 0 ;                while(s+key<j)   s+=key ,cnt++ ;                if((cnt&1)==0)                {                    s += key;                    e = s +key ;                    s = s + 1 ;                }                else                {                    e = s ;                    s = s - key  + 1 ;                }                for(k=s; k<=e&&k<=m; k++)                {                    dp[i][j]+=dp[i-1][j]*dp[i-1][k]*p[j][k];                }            }        }        double ans=-1.0;        int res=0;        for(i=1; i<=m; i++)        {            if(ans<dp[n][i]) ans=dp[n][i],res=i;        }        printf("%d\n",res);    }    return 0;}


原创粉丝点击