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;}